SemaDeclAttr.cpp revision 521f12d3dfdbb0e93d1bcb503d074e67acdc489c
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"
1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h"
166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h"
17acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
18acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
19fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2012bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h"
21797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
27e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
28a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d,
29a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
31a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  if (const ValueDecl *decl = dyn_cast<ValueDecl>(d))
326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
33a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
35a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
39bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
416217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
42755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
44d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
45183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
483568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
493568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
503568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
51d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
52a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
53a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) {
54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  return getFunctionType(d, false) != NULL;
55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
57a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
58d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
59d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
60a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) {
61a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  return isFunction(d)|| isa<ObjCMethodDecl>(d);
62d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
633568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
64620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
65620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
66620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
67a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) {
68620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (isFunctionOrMethod(d))
69620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
70620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
71620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
72620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
73620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
74620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
75d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  return isa<BlockDecl>(d);
76620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
77620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
78d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
79d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
80620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) {
82620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
8372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
84620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
85d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d));
86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
87d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
893568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
90d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
91d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
92d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
93a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) {
9489951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
9572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
96d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
97d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
9889951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_size();
993568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1003568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
101a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) {
10289951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
10372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
104d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
105d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
106bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10789951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
1083568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1093568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
110a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) {
1115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
1125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
1135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  return cast<ObjCMethodDecl>(d)->getResultType();
1145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
116a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) {
117d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
11872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1193568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
120d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
121db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
122d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
1233568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->isVariadic();
1243568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1253568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1263568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
1276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
128183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
129b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
131bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
132506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
133506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
135bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
136506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
137bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
143085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1446217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
145085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
146085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
147085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1486217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
149085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
150085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
152085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
153465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
154085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
155085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
156085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
157085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
158085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
159e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
160e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
161e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
162e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
1633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
1643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
1653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
1663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
1689cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor                                    const AttributeList &Attr, Sema &S) {
169545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
170545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
171803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
172545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
1769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
1789cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
1809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
181f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
182f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
183f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
184f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>();
1859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
1869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
1879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    if (Attr.getNumArgs() != 1) {
1889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
1909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    }
1919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    sizeExpr = static_cast<Expr *>(Attr.getArg(0));
1926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
1959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc());
1979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
198ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
199a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2019cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
2029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
2036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
206803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
208545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
214a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson    TD->addAttr(::new (S.Context) PackedAttr);
2156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
219803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
220fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
22108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
223a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson      FD->addAttr(::new (S.Context) PackedAttr);
2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
22996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
23096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
2313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
23296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
23396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
23663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
23763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
23863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      d->addAttr(::new (S.Context) IBActionAttr());
23963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
24063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
24163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
24263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName();
24363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
24463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
24563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
24663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
24763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (Attr.getNumArgs() > 0) {
24863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
24963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
25063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  }
25163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
25263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
253efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
254efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
25563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    d->addAttr(::new (S.Context) IBOutletAttr());
25663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
257efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
25863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
25963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
26096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
26196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
262857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
263857e918a8a40deb128840308a318bf623d68295fTed Kremenek                                     Sema &S) {
264857e918a8a40deb128840308a318bf623d68295fTed Kremenek
265857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
266857e918a8a40deb128840308a318bf623d68295fTed Kremenek  if (Attr.getNumArgs() > 1) {
267857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
268857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
269857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
270857e918a8a40deb128840308a318bf623d68295fTed Kremenek
271857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
272857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
273857e918a8a40deb128840308a318bf623d68295fTed Kremenek  if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) {
274857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
275857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
276857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
277857e918a8a40deb128840308a318bf623d68295fTed Kremenek
278857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // FIXME: Eventually accept the type argument.
279857e918a8a40deb128840308a318bf623d68295fTed Kremenek  d->addAttr(::new (S.Context) IBOutletCollectionAttr());
280857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
281857e918a8a40deb128840308a318bf623d68295fTed Kremenek
282eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
283bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
284bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
285d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
286fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2875dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
288eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
289eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
290bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
291d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
295bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
298bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
299bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
300eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
301f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek    Expr *Ex = static_cast<Expr *>(*I);
302eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
303ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
304ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
305fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
306fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
307eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
308eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
309bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
310eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
311bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
312eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
313fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
31430bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
315eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
316eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
317bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
318465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
319eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
320eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
321bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    QualType T = getFunctionOrMethodArgType(d, x);
322dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
324fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
325fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
3267fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
327eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
328bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
332bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
333bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
3347fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
33546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
33646bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek      QualType T = getFunctionOrMethodArgType(d, I);
337dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
338d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
33946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
340bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3417fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    if (NonNullArgs.empty()) {
3427fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
3437fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
3447fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    }
345eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
3467fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
3487fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
3497fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  std::sort(start, start + size);
3505961611172f1c210fbbaa55b3c692e13b1fc7be4Ted Kremenek  d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size));
351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
352eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
35311e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic bool isStaticVarOrStaticFunciton(Decl *D) {
35411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (VarDecl *VD = dyn_cast<VarDecl>(D))
35511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return VD->getStorageClass() == VarDecl::Static;
35611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
35711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return FD->getStorageClass() == FunctionDecl::Static;
35811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
35911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
36011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
36111e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
36211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
36311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
36411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
36511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
36611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
36711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
36811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
36911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
37011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
37111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
37211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
37311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
37411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
37511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
37611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
37711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
37811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (const DeclContext *Ctx = d->getDeclContext()) {
37911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Ctx = Ctx->getLookupContext();
38011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    if (!isa<TranslationUnitDecl>(Ctx) && !isa<NamespaceDecl>(Ctx) ) {
38111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
38211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola	dyn_cast<NamedDecl>(d)->getNameAsString();
38311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
38411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
38511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
38611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
38711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
38811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
38911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
39011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
39111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
39211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
39311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
39411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
39511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
39611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
39711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
39811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
39911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
40011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
40111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
40211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
40311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
40411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
40511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (!isStaticVarOrStaticFunciton(d)) {
40611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) <<
40711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      dyn_cast<NamedDecl>(d)->getNameAsString();
40811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
40911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
41011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
41111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
41211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
41311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
41411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
41511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
41611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
41711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
41811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
41911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
42011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    if (Str == 0 || Str->isWide()) {
42111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
42211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
42311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
42411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
42511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
42611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
42711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
42811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
42911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
43011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  d->addAttr(::new (S.Context) WeakRefAttr());
43111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
43211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
433803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
435545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
4363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
4376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
439bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
440545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
4416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
4426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
443bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
4446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
445fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
4463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
4476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
449bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
4506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
451bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
4523d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek  d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
4536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
455bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
456af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
457af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  // check the attribute arguments.
458af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
4593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
460af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
461af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
4625bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
463c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
4645bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4655dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
4665bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
4675bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
468bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
46940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) AlwaysInlineAttr());
470af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
471af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
47276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
47376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  // check the attribute arguments.
47476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  if (Attr.getNumArgs() != 0) {
47576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
47676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
47776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
4781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4792cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
4812cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
4822cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      d->addAttr(::new (S.Context) MallocAttr());
4832cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
4842cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
485fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
486fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
4872cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
48876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
48976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
490b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
491e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara                                     Sema &S) {
4926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
493545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
494e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
495b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek    return false;
4966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
497d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
49819c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
49919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    ValueDecl *VD = dyn_cast<ValueDecl>(d);
5003ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
5013ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
502e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
503e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
504e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara                                     : diag::warn_attribute_wrong_decl_type)
505e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara        << Attr.getName() << 0 /*function*/;
50619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump      return false;
50719c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
5086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
509bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
510b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  return true;
511b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek}
512b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek
513b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
514e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
515e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  assert(Attr.isInvalid() == false);
516e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  d->addAttr(::new (S.Context) NoReturnAttr());
517b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek}
518b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek
519b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
520b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek                                       Sema &S) {
521e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  if (HandleCommonNoReturnAttr(d, Attr, S))
52240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
525bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
526bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
527bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
52804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall      << Attr.getName() << 8 /*function, method, or parameter*/;
529bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
530bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
531bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
532bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
533bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
53473798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
53573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
53673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
5373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
53873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
53973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
540bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
541aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall  if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) &&
542aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall      !isa<TypeDecl>(d)) {
543fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
5445dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
54573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
54673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
547bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
54840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) UnusedAttr());
54973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
55073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
551b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
552b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
553b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (Attr.getNumArgs() != 0) {
554b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
555b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
556b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
557bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
558b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
559186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
560b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
561b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
562b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
563b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  } else if (!isFunctionOrMethod(d)) {
564b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
5655dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
566b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
567b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
568bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
56940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) UsedAttr());
570b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
571b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
5723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
5743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
575fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
576fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0 or 1";
5773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
578bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
5793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
5813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
5823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
5833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
584ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
585ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
586fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
5873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
5883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
5893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
5903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
5913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
592bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
593c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
594fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
5955dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
5963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
5973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
5983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
59940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) ConstructorAttr(priority));
6003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
6013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
6023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
6043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
605fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
606fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner       << "0 or 1";
6073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
608bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
6093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
6103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
6113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
6123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
6133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
614ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
615ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
616fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
6173c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
6183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
6193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
6203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
6213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
622bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6236782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
624fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
6255dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
6263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
6273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
6283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
62940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) DestructorAttr(priority));
6303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
6313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
632803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
634545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
6353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
6366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
638bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
63940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) DeprecatedAttr());
6406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
642bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
643bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  // check the attribute arguments.
644bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
645bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
646bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
647bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
648bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
64940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) UnavailableAttr());
650bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
651bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
652803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
654545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
6553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
6566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
658bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
659545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
6606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
6616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
662bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
664fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
6653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
6666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
668bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
669c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  llvm::StringRef TypeStr = Str->getString();
6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  VisibilityAttr::VisibilityTypes type;
671bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
672c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
6736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::DefaultVisibility;
674c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
6756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility;
676c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
6776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility; // FIXME
678c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
6796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::ProtectedVisibility;
6806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
68108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
6826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
684bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
68540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) VisibilityAttr(type));
6866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6880db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
6890db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner                                    Sema &S) {
6900db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
6910db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
6920db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
6930db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
694bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6950db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
6960db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
6970db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
6980db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
6990db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
700bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
70140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr());
7020db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
7030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
7040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
705fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
7062b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
707fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
708fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
7090db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
710fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
711fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
7126217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
713fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
714fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
715fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
716fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
71740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
718fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
719fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
720bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
721f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
722f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
7232b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
724f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
725f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
726f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
727f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
728f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
729f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
730f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
731f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
73240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr());
733f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
734f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
7359eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
736bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
737fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
7383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
7399eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
7409eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
741bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7429eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
7433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
7449eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
7459eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
746bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7479eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  BlocksAttr::BlocksAttrTypes type;
74892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
7499eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
7509eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
751fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
7523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
7539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
7549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
755bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
75640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) BlocksAttr(type));
7579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
7589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
759770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
760770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
761770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
762fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
763fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0, 1 or 2";
764770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
765bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
766bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
767770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
768770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
769770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(0));
770770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
771ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
772ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
773fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
7743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
775770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
776770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
777770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
778bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
779770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
780fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
781fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
782770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
783770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
784770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
785770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
786770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
787770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
788770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(1));
789770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
790ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
791ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
792fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
7933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
794770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
795770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
796770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
797bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
798770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
799770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
800770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
801fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
802fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
803770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
804770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
805770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
806770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
807770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
808183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
809897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
810bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
811897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
812897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
813897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
814897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
815bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
816897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
8173bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
818770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
819bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
820770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
821770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
8223bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
823770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
8242f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
8252f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (isa<BlockDecl>(d)) {
826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
827bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
8282f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
8292f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
8302f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
831daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
832bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
833183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
8342f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
8353bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
8363bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
8372f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
8382f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
839ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
8402f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
841ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
8422f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
8432f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
844770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
845fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
846ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
847770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
848770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
84940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
850770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
851770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
852026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
853026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
854026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
855026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
856026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
857026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
858026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
859f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
860026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8615dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
862026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
863026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
864bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
865f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
866f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
867f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
868f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
869f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
870f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
871f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
872f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
873f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
874f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
875f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
876f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
877d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes  D->addAttr(::new (S.Context) WarnUnusedResultAttr());
878026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
879026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
880026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
8816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
882545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8866e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
887f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  /* weak only applies to non-static declarations */
88811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (isStaticVarOrStaticFunciton(D)) {
889f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) <<
890f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian      dyn_cast<NamedDecl>(D)->getNameAsString();
891f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
892f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
893f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
8946e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // TODO: could also be applied to methods?
8956e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
8966e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8975dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
8986e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
8996e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
900bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
90140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakAttr());
9026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9046e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
9056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
9066e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
9076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
9086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
909bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
9106e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
9116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
9126e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
9136e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
9146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    isDef = (!VD->hasExternalStorage() || VD->getInit());
9156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
9166fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis    isDef = FD->getBody();
917d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian  } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
918d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian    // We ignore weak import on properties and methods
9191c90f4dc686ab872013544664c797604a309c563Mike Stump    return;
9205f8f8571c52dbf12fdefb15d2fedbcccb212c15cFariborz Jahanian  } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) {
921c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian    // Don't issue the warning for darwin as target; yet, ignore the attribute.
9223be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian    if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin ||
923c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian        !isa<ObjCInterfaceDecl>(D))
924c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9253be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian        << Attr.getName() << 2 /*variable and function*/;
9263be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian      return;
9276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
9286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
9296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // Merge should handle any subsequent violations.
9306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (isDef) {
931bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
9326e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar           diag::warn_attribute_weak_import_invalid_on_definition)
9336e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar      << "weak_import" << 2 /*variable and function*/;
9346e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
9356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
9366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
93740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr());
9386e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
9396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
9406f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
9416f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                    Sema &S) {
9426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
9436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  if (Attr.getNumArgs() != 3) {
9442b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
9456f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
9466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
9476f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
9486f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
9496f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
9506f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    Expr *E = static_cast<Expr *>(Attr.getArg(i));
9516f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
952ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
953ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
9546f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
9556f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
9566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
9576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
9586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
9596f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
96040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
9616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
9626f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
9636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
964026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
96517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
96617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
96717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
96817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
96917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
97017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
97117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
97217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
973797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
974797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
97517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
976797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
97717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
97817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
9791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
980797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
981bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
982a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
983a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
984a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
985797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
986797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
9871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
988a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
989a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
990a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
991a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
992a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
993a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
9943d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek  D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString()));
99517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
99617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
9976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
998803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1000545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
10013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
10026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1004bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
100540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) NoThrowAttr());
10066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1008232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1009232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1010232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
10113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1012232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1013232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1014bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
101540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) ConstAttr());
1016232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1017232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1018232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1019232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1020232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
10213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1022232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1023232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1024bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
102540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) PureAttr());
1026232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1027232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1028f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1029bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1030f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1031f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1032f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1033bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1034f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1035f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1036f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1037f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1038bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1039f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
1040bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1041f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1042f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1043f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1044f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1045bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1046f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1047c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1048c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: The lookup source location should be in the attribute, not the
1049c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // start of the attribute.
1050f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1051c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor    = S.LookupSingleName(S.TUScope, Attr.getParameterName(), Attr.getLoc(),
1052f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall                         Sema::LookupOrdinaryName);
1053f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
105489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1055f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1056f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1057f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1058bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1059f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1060f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
106189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
1062f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1063f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1064f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1065f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1066f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
106789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
1068f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1069f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1070f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1071bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
107289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
107389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
107489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
107589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1076d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman  if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
1077bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
107889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
107989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
108089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
108189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1082bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
108340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) CleanupAttr(FD));
1084f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1085f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1086bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1087bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1088bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
10895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Attr.getNumArgs() != 1) {
10905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
10915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
10925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
10935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
10945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
10955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << Attr.getName() << 0 /*function*/;
10965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
10975b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1098bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // FIXME: in C++ the implicit 'this' function parameter also counts.  this is
1099bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // needed in order to be compatible with GCC the index must start with 1.
11005b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
11015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
11025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
11035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
11045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1105ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1106ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
11075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
11095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
11105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1111bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
11135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
11145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
11155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
11165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1117bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1119bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
11215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1122bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
11245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
11255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
11265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
11276217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
11285b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
11295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1130bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
11315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
11325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1133bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
11345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Ty = getFunctionOrMethodResultType(d);
11355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
11365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
11375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
11386217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
11395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
11405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1141bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
11425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
11435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1145bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
114640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
11475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
11485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
11492b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
11502b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
11512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
11522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
11532b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
11543c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
11552b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
11562b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
11572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
11582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
11592b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
11602b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
11612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
11622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
11632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
11642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
11652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
11662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
11672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
11682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
11692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
11702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
11712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
11722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
11732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "zcmn_err")
11742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
11752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1176bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1177bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
11783c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
11793c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
11802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
11812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
11822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1183521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
1184521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
1185521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
1186521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian                                   Sema &S) {
1187521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
1188521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1189521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1190521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1191521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1192521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
1193521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1194521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1195521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1196521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1197521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  Expr *priorityExpr = static_cast<Expr *>(Attr.getArg(0));
1198521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
1199521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1200521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1201521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1202521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
1203521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1204521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1205521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1206521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  unsigned prioritynum = static_cast<unsigned>(priority.getZExtValue() * 8);
1207521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
1208521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1209521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
1210521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1211521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1212521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1213521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  d->addAttr(::new (S.Context) InitPriorityAttr(prioritynum));
1214521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
1215521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1216bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1217bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1218803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
12196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1220545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1221fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
12236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1226545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
12273c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
12286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1231620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1232fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
12335dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
12346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12373568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
12386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
12396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
124001eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Format = Attr.getParameterName()->getName();
12416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
12432b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
12442b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
12452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
12462b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
12472b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
12483c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
12493c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
12503c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
12513c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
12522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1253fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
125401eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
12556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
1259545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1260803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1261ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1262ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1263fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
12643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
12656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12684fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  // FIXME: We should handle the implicit 'this' parameter in a more generic
12694fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  // way that can be used for other arguments.
12704fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  bool HasImplicitThisParam = false;
12714fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) {
12724fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson    if (MD->isInstance()) {
12734fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson      HasImplicitThisParam = true;
12744fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson      NumArgs++;
12754fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson    }
12764fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  }
12771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1279fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
12803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
12816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
12856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1286bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12874a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
12884a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
12894a2614e94672c47395abcde60518776fbebec589Sebastian Redl      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
12904a2614e94672c47395abcde60518776fbebec589Sebastian Redl        << "a string type" << IdxExpr->getSourceRange();
12914a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
12924a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
12934a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
12944a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
12951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
12973568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
12986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1300085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1301fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1302fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1303085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1304085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
13052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1306390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1307390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1308803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1309390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1310fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1311fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
13126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1313bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
13146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
13156217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1316390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1317fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1318fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
13196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
1323545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1324803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1325ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1326ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1327fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
13296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
13336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
13343568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
13356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
13366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1337803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
13386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
13396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
13406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
13433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
13442b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
13456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1346fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1347fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
13486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
13496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
13506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
13516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1352fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
13533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
13546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13573d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek  d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(),
13582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
13596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
13620b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
13636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1364545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
13653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
13666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
13700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
1371bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
13720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
13730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
13740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
13750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = dyn_cast<RecordDecl>(d);
13760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
13770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1378fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
13795dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 1 /*union*/;
13806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1384bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
13850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
13860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
13870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
13880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
138917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
139017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
13910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
13920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
13930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
13940c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1395bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
13960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
13970c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
13980c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (FirstType->isFloatingType() || FirstType->isVectorType()) {
1399bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
14000c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor           diag::warn_transparent_union_attribute_floating);
14010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
14020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1403bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
14040c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
14050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
14060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
14070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
14080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
14090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
14100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
14110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1412bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
14130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
1414bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
14150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
14160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
14170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1418bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
14190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
14200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
1421bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1422bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1423bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
14246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
142540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr());
14266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
14296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1430545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
14313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
14326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1434797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
1435797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1436bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
14386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
14396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
1440797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
14416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
14433d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek  d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString()));
14446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1446803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
14476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1448545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
14493c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
14506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1452bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1453bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
1454bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
1455bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
14566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
1458545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
14596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
14607549c5589ac0d2087e55f2bdd4854adef23f29fdDaniel Dunbar    // (For now we just use 128 bits which is the maximum on X86).
14616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
146240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    d->addAttr(::new (S.Context) AlignedAttr(Align));
14636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1465bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
146649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
146749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
1468ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (alignmentExpr->isTypeDependent() || alignmentExpr->isValueDependent() ||
1469ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1470fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1471fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "aligned" << alignmentExpr->getSourceRange();
147249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
147349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
1474396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
1475bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
1476396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar      << alignmentExpr->getSourceRange();
1477396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
1478396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
1479396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
148040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
14816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1482fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1483bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive
1484bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
1485fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
1486bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
1487bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
1488bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
14890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1490fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
1491fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
1492fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1493fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
1494fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
14953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1496fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1497fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1498fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1499fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
1500fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
15010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1502fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1503fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1504210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
150501eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Str = Attr.getParameterName()->getName();
1506fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1507fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
1508210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
1509210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
1510fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1511fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1512fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
151373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
1514210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
1515fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
151673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
151773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
151873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
151973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
152073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
152173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
152273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
152373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
152473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
152573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
152673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
152773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
152873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
152973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
153073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
153173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1532fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1533fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1534fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1535fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1536210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
15370b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1538210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
15390b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1540fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1541fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
1542210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
15430b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1544fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1545fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1546fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1547fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
1548fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1549fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
1550fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1551fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
1552fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
1553fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1554fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1555fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1556fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
155773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1558183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
155973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
156073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
15612ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
156273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
156373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
156473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
156573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
156673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
156773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
156873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
156973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
157073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1571390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
1572390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
1573390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
1574390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
1575f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
1576f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
1577fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
1578fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
1579fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
15803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1581fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1582fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
15833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1584fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1585fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
158673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
158773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
158873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
158973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1590fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
15910b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
1592fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
15930b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
1594fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1595fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
159673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
159773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
159873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
159973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1600fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
16010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
1602fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
16030b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
1604fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1605fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
1606fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
16070b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
1608fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
16090b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
1610fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
16110b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
1612fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1613fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
1614fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
16150b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
1616fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
1617aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
1618aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
1619aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
1620aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
1621fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
1622aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
1623aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
1624aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
1625aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
1626fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
162773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
162873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
162973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1630f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
1631f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
1632f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1633f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
1634f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
1635f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
1636f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
1637f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
1638f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
163973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1640fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1641fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
164273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
164373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
1644fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1645fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1646fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
1647ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
1648ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
1649a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
1650ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
1651fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
1652fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
16530744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
16541feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1655d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
1656d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
1657d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1658d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1659d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1660e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
16615bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (!isFunctionOrMethod(d)) {
1662d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16635dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
1664d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1665d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1666bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16671feade8e520be483293dbf55eb57a51720899589Mike Stump  d->addAttr(::new (S.Context) NoDebugAttr());
1668d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
1669d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
16701feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
16715bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
16725bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
16735bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
16745bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
16755bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1676bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1677c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
16785bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16795dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
16805bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
16815bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1682bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16831feade8e520be483293dbf55eb57a51720899589Mike Stump  d->addAttr(::new (S.Context) NoInlineAttr());
16845bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
16855bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
1686cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
168726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
168826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
168926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
169026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
169126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
1692bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1693c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
1694c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
169526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16965dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
169726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
169826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
1699bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17000130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
1701cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
1702c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
1703c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
1704bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
170540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) GNUInlineAttr());
170626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
170726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
1708e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnarastatic void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1709e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
1710e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
1711e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  assert(Attr.isInvalid() == false);
1712e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
1713e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  switch (Attr.getKind()) {
1714e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
1715e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    d->addAttr(::new (S.Context) FastCallAttr());
1716e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
1717e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
1718e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    d->addAttr(::new (S.Context) StdCallAttr());
1719e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
1720f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
1721f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor    d->addAttr(::new (S.Context) ThisCallAttr());
1722e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
1723e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    d->addAttr(::new (S.Context) CDeclAttr());
1724e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
1725e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
1726e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
1727e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
1728e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
1729e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
1730e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
1731ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1732ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  // check the attribute arguments.
1733ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (Attr.getNumArgs() != 1) {
173455d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1735ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
1736ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
173755d3aaf9a537888734762170823daf750ea9036dEli Friedman
1738ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (!isFunctionOrMethod(d)) {
1739ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
17405dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
1741ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
1742ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
174355d3aaf9a537888734762170823daf750ea9036dEli Friedman
174455d3aaf9a537888734762170823daf750ea9036dEli Friedman  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
174555d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
1746ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
1747ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
174855d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
174955d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
175055d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
175155d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
175255d3aaf9a537888734762170823daf750ea9036dEli Friedman
1753264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov  if (S.Context.Target.getRegParmMax() == 0) {
1754264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
175555d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
175655d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
175755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
175855d3aaf9a537888734762170823daf750ea9036dEli Friedman
1759348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
1760264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
1761264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
176255d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
176355d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
176455d3aaf9a537888734762170823daf750ea9036dEli Friedman
176540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
1766ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
1767ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
1768bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1769bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // check the attribute arguments.
1770bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Attr.getNumArgs() != 0) {
1771bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1772bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1773bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1774bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1775bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isa<CXXRecordDecl>(d)
1776bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt   && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) {
1777bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(),
1778bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1779bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                   : diag::warn_attribute_wrong_decl_type)
1780bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      << Attr.getName() << 7 /*virtual method or class*/;
1781bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1782bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
17837725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
17847725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
17857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
17867725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<FinalAttr>()) {
17877725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final";
17887725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
17897725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
1790bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1791bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  d->addAttr(::new (S.Context) FinalAttr());
1792bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1793bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
17940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
17957725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt// C++0x member checking attributes
17967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===//
17977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
17987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) {
17997725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
18007725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
18017725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
18027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
18037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18047725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<CXXRecordDecl>(d)) {
18057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
18067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
18077725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
18087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 9 /*class*/;
18097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
18107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
18117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<BaseCheckAttr>()) {
18137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check";
18147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
18157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
18167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  d->addAttr(::new (S.Context) BaseCheckAttr());
18187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
18197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
18217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
18227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
18237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
18247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
18257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18267725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<RecordDecl>(d->getDeclContext())) {
18277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    // FIXME: It's not the type that's the problem
18287725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
18297725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
18307725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
18317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 11 /*member*/;
18327725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
18337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
18347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
18367725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18377725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<HidingAttr>()) {
18387725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding";
18397725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
18407725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
18417725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18427725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  d->addAttr(::new (S.Context) HidingAttr());
18437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
18447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
18467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
18477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
18487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
18497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
18507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) {
18527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    // FIXME: It's not the type that's the problem
18537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
18547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
18557725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
18567725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 10 /*virtual method*/;
18577725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
18587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
18597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
18617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<OverrideAttr>()) {
18637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override";
18647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
18657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
18667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18677725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  d->addAttr(::new (S.Context) OverrideAttr());
18687725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
18697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
18707725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===//
1871b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
1872b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
1873b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1874b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
1875b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek                                        Sema &S) {
1876b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
18775dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  QualType RetTy;
1878bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18795dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
18805dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = MD->getResultType();
18815dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
18825dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = FD->getResultType();
18835dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
188421531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    SourceLocation L = Attr.getLoc();
188521531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
188621531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek        << SourceRange(L, L) << Attr.getName() << 3 /* function or method */;
1887b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
1888b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
1889bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18906217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>()
1891183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        || RetTy->getAs<ObjCObjectPointerType>())) {
189221531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    SourceLocation L = Attr.getLoc();
189321531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
189421531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek      << SourceRange(L, L) << Attr.getName();
1895bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
18965dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
1897bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1898b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  switch (Attr.getKind()) {
1899b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
1900b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
1901b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
190231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
190331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr());
190431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
190531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
190631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr());
190731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
1908b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
190940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
1910b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1911b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
191240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
1913b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1914b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
1915b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
1916b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1917f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
1918f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
1919f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis         Attr.getKind() == AttributeList::AT_dllexport;
1920f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
1921f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
1922b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
19230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
19240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
19250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1926a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1927803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
1928bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
1929bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
1930bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D,
1931bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump                                 const AttributeList &Attr, Sema &S) {
1932e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  if (Attr.isInvalid())
1933e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
1934e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
1935f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
1936f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis    // FIXME: Try to deal with other __declspec attributes!
1937290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman    return;
1938803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
193963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  case AttributeList::AT_IBAction:            HandleIBAction(D, Attr, S); break;
1940857e918a8a40deb128840308a318bf623d68295fTed Kremenek    case AttributeList::AT_IBOutlet:          HandleIBOutlet(D, Attr, S); break;
1941857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
1942857e918a8a40deb128840308a318bf623d68295fTed Kremenek      HandleIBOutletCollection(D, Attr, S); break;
1943803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
1944ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
19456e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
1946bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
1947bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
1948803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
19497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_alias:       HandleAliasAttr       (D, Attr, S); break;
19507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_aligned:     HandleAlignedAttr     (D, Attr, S); break;
1951bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
1952af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
1953b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
1954bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
19557725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_annotate:    HandleAnnotateAttr    (D, Attr, S); break;
19567725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_base_check:  HandleBaseCheckAttr   (D, Attr, S); break;
1957bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
19587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                      HandleDependencyAttr  (D, Attr, S); break;
19597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
19607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_deprecated:  HandleDeprecatedAttr  (D, Attr, S); break;
19617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_destructor:  HandleDestructorAttr  (D, Attr, S); break;
19623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
19639cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    HandleExtVectorTypeAttr(scope, D, Attr, S);
19643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
19657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_final:       HandleFinalAttr       (D, Attr, S); break;
19667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format:      HandleFormatAttr      (D, Attr, S); break;
19677725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format_arg:  HandleFormatArgAttr   (D, Attr, S); break;
19687725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr   (D, Attr, S); break;
19697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_hiding:      HandleHidingAttr      (D, Attr, S); break;
19707725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_mode:        HandleModeAttr        (D, Attr, S); break;
19717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_malloc:      HandleMallocAttr      (D, Attr, S); break;
19727725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nonnull:     HandleNonNullAttr     (D, Attr, S); break;
19737725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;
19747725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;
19757725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_override:    HandleOverrideAttr    (D, Attr, S); break;
1976b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1977b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
197831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
197931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
1980b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
1981b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
1982b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    HandleNSReturnsRetainedAttr(D, Attr, S); break;
1983b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
19846f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
19856f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    HandleReqdWorkGroupSize(D, Attr, S); break;
19866f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
1987521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
1988521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      HandleInitPriorityAttr(D, Attr, S); break;
1989521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
19907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_packed:      HandlePackedAttr      (D, Attr, S); break;
19917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_section:     HandleSectionAttr     (D, Attr, S); break;
19927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
19937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unused:      HandleUnusedAttr      (D, Attr, S); break;
19947725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_used:        HandleUsedAttr        (D, Attr, S); break;
19957725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_visibility:  HandleVisibilityAttr  (D, Attr, S); break;
1996026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
1997026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
19987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak:        HandleWeakAttr        (D, Attr, S); break;
199911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  case AttributeList::AT_weakref:     HandleWeakRefAttr     (D, Attr, S); break;
20007725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak_import: HandleWeakImportAttr  (D, Attr, S); break;
2001803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
2002803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
2003803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
20040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
20050db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
20060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
2007f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
20087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nsobject:    HandleObjCNSObject    (D, Attr, S); break;
20097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_blocks:      HandleBlocksAttr      (D, Attr, S); break;
20107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_sentinel:    HandleSentinelAttr    (D, Attr, S); break;
20117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_const:       HandleConstAttr       (D, Attr, S); break;
20127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_pure:        HandlePureAttr        (D, Attr, S); break;
20137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_cleanup:     HandleCleanupAttr     (D, Attr, S); break;
20147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nodebug:     HandleNoDebugAttr     (D, Attr, S); break;
20157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noinline:    HandleNoInlineAttr    (D, Attr, S); break;
20167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_regparm:     HandleRegparmAttr     (D, Attr, S); break;
2017bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
20185e204486a7dd1e5f7e14e941a2c7e707a8ad1a3bChris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
201905f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
202005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
202104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
202204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
202304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
2024f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
2025e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    HandleCallConvAttr(D, Attr, S);
202604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
2027803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
202882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
202982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
203082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
203182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2032803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
2033803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2034803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2035803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
2036803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
2037803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
20389cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) {
203911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
204011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    ProcessDeclAttribute(S, D, *l, *this);
204111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
204211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
204311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
204411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
204511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
204611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
204711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
204811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola	dyn_cast<NamedDecl>(D)->getNameAsString();
204911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
2050803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2051803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2052803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
2053e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
2054e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
20551eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
20567b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
2057e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
2058e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
2059e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
2060e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
2061a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
2062b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
2063b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
2064b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange());
2065b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
2066e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
2067e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
2068e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                           VD->getLocation(), II,
2069a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
207016573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
207116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
2072b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
2073b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
2074b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange());
2075b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
2076e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2077e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
2078e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
2079e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
2080e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
2081e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
20827b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
2083c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
2084c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
2085c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
2086c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
2087c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
20883d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek    NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName()));
2089c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NewD->addAttr(::new (Context) WeakAttr());
2090c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
2091c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
2092c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
2093c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
2094c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
2095c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
2096c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
2097c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
2098c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    ND->addAttr(::new (Context) WeakAttr());
2099e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2100e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
2101e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
21020744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
21030744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
21040744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
21059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
2106e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  // Handle #pragma weak
2107e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
2108e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    if (ND->hasLinkage()) {
2109e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier());
2110e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      if (W != WeakInfo()) {
21117b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn        // Identifier referenced by #pragma weak before it was declared
21127b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn        DeclApplyPragmaWeak(S, ND, W);
2113e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn        WeakUndeclaredIdentifiers[ND->getIdentifier()] = W;
2114e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
2115e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
2116e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2117e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
21180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
21190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
21209cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
2121bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
21230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
21240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
21250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
21260744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
21270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
21289cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      ProcessDeclAttributeList(S, D, Attrs);
2129bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21300744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
21310744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
21329cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
21330744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
213454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
213554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// PushParsingDeclaration - Enter a new "scope" of deprecation
213654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// warnings.
213754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall///
213854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// The state token we use is the start index of this scope
213954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// on the warning stack.
214054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallAction::ParsingDeclStackState Sema::PushParsingDeclaration() {
214154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclDepth++;
21422f514480c448708ec382a684cf5e035d3a827ec8John McCall  return (ParsingDeclStackState) DelayedDiagnostics.size();
214354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
214454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
214554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallvoid Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) {
214654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
214754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclDepth--;
214854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
21492f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (DelayedDiagnostics.empty())
215054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
215154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
215254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  unsigned SavedIndex = (unsigned) S;
21532f514480c448708ec382a684cf5e035d3a827ec8John McCall  assert(SavedIndex <= DelayedDiagnostics.size() &&
215454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall         "saved index is out of bounds");
215554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
215658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  unsigned E = DelayedDiagnostics.size();
215758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
21582f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
21592f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
21602f514480c448708ec382a684cf5e035d3a827ec8John McCall  Decl *D = Ctx ? Ctx.getAs<Decl>() : 0;
21612f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (D) {
21622f514480c448708ec382a684cf5e035d3a827ec8John McCall    // We really do want to start with 0 here.  We get one push for a
21632f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
21642f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
21652f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
21662f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
21672f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
216858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    for (unsigned I = 0; I != E; ++I) {
21692f514480c448708ec382a684cf5e035d3a827ec8John McCall      if (DelayedDiagnostics[I].Triggered)
21702f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
21712f514480c448708ec382a684cf5e035d3a827ec8John McCall
21722f514480c448708ec382a684cf5e035d3a827ec8John McCall      switch (DelayedDiagnostics[I].Kind) {
21732f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
21742f514480c448708ec382a684cf5e035d3a827ec8John McCall        HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D);
21752f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
21762f514480c448708ec382a684cf5e035d3a827ec8John McCall
21772f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
21782f514480c448708ec382a684cf5e035d3a827ec8John McCall        HandleDelayedAccessCheck(DelayedDiagnostics[I], D);
21792f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
218054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
218154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
218254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
218354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
218458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
218558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  for (unsigned I = SavedIndex; I != E; ++I)
218658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    DelayedDiagnostics[I].destroy();
218758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
21882f514480c448708ec382a684cf5e035d3a827ec8John McCall  DelayedDiagnostics.set_size(SavedIndex);
21892f514480c448708ec382a684cf5e035d3a827ec8John McCall}
21902f514480c448708ec382a684cf5e035d3a827ec8John McCall
21912f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
21922f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
21932f514480c448708ec382a684cf5e035d3a827ec8John McCall    if (D->hasAttr<DeprecatedAttr>())
21942f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
21952f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
21962f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
21972f514480c448708ec382a684cf5e035d3a827ec8John McCall}
21982f514480c448708ec382a684cf5e035d3a827ec8John McCall
21992f514480c448708ec382a684cf5e035d3a827ec8John McCallvoid Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD,
22002f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
22012f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
22022f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
22032f514480c448708ec382a684cf5e035d3a827ec8John McCall
22042f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
22052f514480c448708ec382a684cf5e035d3a827ec8John McCall  Diag(DD.Loc, diag::warn_deprecated)
22062f514480c448708ec382a684cf5e035d3a827ec8John McCall    << DD.DeprecationData.Decl->getDeclName();
220754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
220854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
220954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallvoid Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) {
221054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
221154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (ParsingDeclDepth) {
22122f514480c448708ec382a684cf5e035d3a827ec8John McCall    DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D));
221354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
221454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
221554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
221654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
221754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
221854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
221954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
222054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  Diag(Loc, diag::warn_deprecated) << D->getDeclName();
222154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
2222