SemaDeclAttr.cpp revision 07d7e7a6b10f798459f350b792713db2fb3e9365
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
142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h"
1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h"
166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h"
17384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
18acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
20fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2119510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
229c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
23797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
28e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
29e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
30e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
31a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d,
32a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
34a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  if (const ValueDecl *decl = dyn_cast<ValueDecl>(d))
356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
36a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
38a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
42bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
446217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
45755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
466217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
47d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
48183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
54d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) {
57a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  return getFunctionType(d, false) != NULL;
58a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
59a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
60a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
61d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
62d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
63a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) {
64a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  return isFunction(d)|| isa<ObjCMethodDecl>(d);
65d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
663568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
67620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
68620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
69620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
70a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) {
71620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (isFunctionOrMethod(d))
72620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
73620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
74620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
75620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
76620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
77620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
78d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  return isa<BlockDecl>(d);
79620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
80620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
81d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
82d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
83620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
84a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) {
85620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
8672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
87620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
88d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d));
89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
90d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
913568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
923568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
93d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
94d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
95d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
96a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) {
9789951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
9872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
99d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
100d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
10189951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_size();
1023568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1033568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
104a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) {
10589951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
10672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
107d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
108d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
109bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11089951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
1113568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1123568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
113a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) {
1145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
1155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
1165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  return cast<ObjCMethodDecl>(d)->getResultType();
1175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
119a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) {
120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
12172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
123d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
124db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
125d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
1263568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->isVariadic();
1273568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1283568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1293568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruthstatic bool isInstanceMethod(const Decl *d) {
13107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(d))
13207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
13307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
13407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
13507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
137183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
138b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
141506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
142506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
145506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
146bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
152085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1536217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
154085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
155085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
156085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1576217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
158085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
159085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
160bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
161085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
162465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
163085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
164085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
165085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
166085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
167085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
168e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
169e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
170e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
171e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
1723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
1733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
1743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
1753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
1779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor                                    const AttributeList &Attr, Sema &S) {
178545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
179545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
180803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
181545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
1826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
183bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
1859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
1879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
1899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
190f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
191f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
192f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
193f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>();
1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
1959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    if (Attr.getNumArgs() != 1) {
1979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1989cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
1999cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    }
2009cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    sizeExpr = static_cast<Expr *>(Attr.getArg(0));
2016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
2049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
2059ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
2069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
207ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
208a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
209bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2109cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
2119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
2126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
215803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
217545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
221bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
223cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
228803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
229fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
23008631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
2316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
232cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
23896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
23996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
2403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
24196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
24296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
243bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
24563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
24663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
247cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
24863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
24963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
25063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
25163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName();
25263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
25363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
25463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
25563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
25663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (Attr.getNumArgs() > 0) {
25763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
25863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
25963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  }
26063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
26163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
262efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
263efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
264cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
26563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
266efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
26763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
26863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
26996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
27096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
271857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
272857e918a8a40deb128840308a318bf623d68295fTed Kremenek                                     Sema &S) {
273857e918a8a40deb128840308a318bf623d68295fTed Kremenek
274857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
275a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
276857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
277857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
278857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
279857e918a8a40deb128840308a318bf623d68295fTed Kremenek
280857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
281857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
282857e918a8a40deb128840308a318bf623d68295fTed Kremenek  if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) {
283857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
284857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
285857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
2863a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian  if (const ValueDecl *VD = dyn_cast<ValueDecl>(d))
2873a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
2883a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
2893a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
2903a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
2913a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
2923a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
2933a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
2943a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
2953a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
2963a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
2973a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
2983a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
299a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
300a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
301a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
3023a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
303b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
304a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian                        S.getScopeForContext(d->getDeclContext()->getParent()));
305a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
306a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
307a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
308a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
309b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
310a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
311a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
312a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
313a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
314a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
315a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
316a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
317a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
318a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
319cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
320cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
321857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
322857e918a8a40deb128840308a318bf623d68295fTed Kremenek
323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
324bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
325bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
326d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
327fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3285dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
33207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
33307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
33407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
33507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
338eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
339bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
340eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
341eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
342bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
343bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
344eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
345f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek    Expr *Ex = static_cast<Expr *>(*I);
346eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
347ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
348ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
349fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
350fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
352eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
353bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
354eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
355bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
356eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
35830bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
359eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
360eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
361bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
362465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
36307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
36407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
36507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
36607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
36707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
36807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
36907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
37007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
37107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
372eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
373eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
374bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    QualType T = getFunctionOrMethodArgType(d, x);
375dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
376eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
377c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
378fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
3797fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
380eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
381bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
382eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
383eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
384bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
385bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
386bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
3877fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
38846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
38946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek      QualType T = getFunctionOrMethodArgType(d, I);
390dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
391d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
392ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian      else if (const RecordType *UT = T->getAsUnionType()) {
393ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian        if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
394ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian          RecordDecl *UD = UT->getDecl();
395ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian          for (RecordDecl::field_iterator it = UD->field_begin(),
396ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian               itend = UD->field_end(); it != itend; ++it) {
397ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian            T = it->getType();
398ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian            if (T->isAnyPointerType() || T->isBlockPointerType()) {
399ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian              NonNullArgs.push_back(I);
400ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian              break;
401ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian            }
402ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian          }
403ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian        }
404ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian      }
40546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
406bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
407ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
40860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
40960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
41060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
41160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
41260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
4137fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
41460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
415eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
4167fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
4177fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
4187fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
419dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
420cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
421cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
422eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
423eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
424dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekstatic void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
425dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
426dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
427dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
428dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
429dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
430dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
4312a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
4322a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
433dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
434dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
435dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
436dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
437dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
438dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
439dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
440cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
4412a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
4422a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
443cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
444dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
445dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
446dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
447dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4482a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4492a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
450cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
451dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
452dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
453dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
454dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
457cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
458dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
459dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
460dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
461dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
462dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4632a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4642a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
4652a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
4662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
467dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
468dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
469dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!isFunction(d) || !hasFunctionProto(d)) {
470dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName()
471dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << 0 /*function*/;
472dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
473dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
47507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
47607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
47707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
47807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::StringRef Module = AL.getParameterName()->getName();
481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
482dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
483dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
484dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
485dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
486dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::SmallVector<unsigned, 10> OwnershipArgs;
487dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
4882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
4892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
490dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
491dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Expr *IdxExpr = static_cast<Expr *>(*I);
492dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
493dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
494dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
495dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
496dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
497dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
498dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
501dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
502dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
503dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
504dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
505dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
506dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
50807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
50907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
51007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
51107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
51207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
51307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
51407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
51507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
51607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
517dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
518cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
519cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
520dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
521dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      QualType T = getFunctionOrMethodArgType(d, x);
522dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
523dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
524dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
525cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
526dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
527dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
528dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
530dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
531dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
532cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
533dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
534dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
535dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0));
536dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
537dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
538dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
539dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
540dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
541dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
542dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
543dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
544dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
545dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
546dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5472a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
5482a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
550dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
551dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
552cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
553cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          i = d->specific_attr_begin<OwnershipAttr>(),
554cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          e = d->specific_attr_end<OwnershipAttr>();
555cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
556cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
557cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
558cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
559cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
560cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
561cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
562dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
563dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
564dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
565dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
566dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
567dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
568dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
570dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
571dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
572cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
573cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
574cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
575cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
576dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
577cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
578cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
579cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
580dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
581dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
58211e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic bool isStaticVarOrStaticFunciton(Decl *D) {
58311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (VarDecl *VD = dyn_cast<VarDecl>(D))
584d931b086984257de68868a64a235c2b4b34003fbJohn McCall    return VD->getStorageClass() == SC_Static;
58511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
586d931b086984257de68868a64a235c2b4b34003fbJohn McCall    return FD->getStorageClass() == SC_Static;
58711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
58811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
58911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
59011e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
59111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
59211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
59311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
59411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
59511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
59611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
59711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
59811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
59911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
60011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
60111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
60211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
60311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
60411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
60511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
60611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
6077a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  const DeclContext *Ctx = d->getDeclContext()->getRedeclContext();
6087a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
6097a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
6107a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl        dyn_cast<NamedDecl>(d)->getNameAsString();
6117a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
61211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
61311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
61411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
61511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
61611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
61711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
61811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
61911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
62011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
62111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
62211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
62311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
62411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
62511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
62611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
62711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
62811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
62911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
63011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
63111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
63211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (!isStaticVarOrStaticFunciton(d)) {
63311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) <<
63411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      dyn_cast<NamedDecl>(d)->getNameAsString();
63511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
63611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
63711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
63811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
63911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
64011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
64111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
64211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
64311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
64411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
64511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
64611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
64711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    if (Str == 0 || Str->isWide()) {
64811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
64911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
65011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
65111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
65211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
65311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
654cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
65511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
65611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
657cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
65811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
65911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
660803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
662545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
6633c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
6646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
666bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
667545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
6686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
670bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
672fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
6733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
6746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
676bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
678bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
679cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
6806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
682dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbarstatic void HandleNakedAttr(Decl *d, const AttributeList &Attr,
683dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar                                   Sema &S) {
684dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
685dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  if (Attr.getNumArgs() != 0) {
686dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
687dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
688dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
689dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
690dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  if (!isa<FunctionDecl>(d)) {
691dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
692dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar      << Attr.getName() << 0 /*function*/;
693dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
694dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
695dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
696dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
697dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
698dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
699bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
700af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
701dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
702af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
7033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
704af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
705af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
7065bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
707c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
7085bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
709dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar      << Attr.getName() << 0 /*function*/;
7105bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
7115bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
712bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
713cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
714af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
715af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
71676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
717dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
71876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  if (Attr.getNumArgs() != 0) {
71976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
72076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
72176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
7221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7232cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
7241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
7252cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
726cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
7272cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
7282cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
729fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
730fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
7312cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
73276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
73376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
734b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
735b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
736b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  assert(Attr.isInvalid() == false);
737b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context));
738b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
739b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
740b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
741b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek                                       Sema &S) {
742b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
743b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
744b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
745b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
746545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
747e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
748b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek    return;
7496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
750b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
75119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
75219c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    ValueDecl *VD = dyn_cast<ValueDecl>(d);
7533ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
7543ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
755e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
756e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
757b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
758b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      << Attr.getName() << 0 /*function*/;
759b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
76019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
7616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
762b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
763b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
7646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
76635cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
76735cc9627340b15232139b3c43fcde5973e7fad30John Thompsonstatic void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
76835cc9627340b15232139b3c43fcde5973e7fad30John Thompson                                       Sema &S) {
76935cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
77035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
77135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
77235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  According to the PPU ABI specifications, a class with a single member of vector type is returned in
77335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  memory when used as the return value of a function. This results in inefficient code when implementing
77435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  vector classes. To return the value in a single vector register, add the vecreturn attribute to the class
77535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  definition. This attribute is also applicable to struct types.
77635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
77735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
77835cc9627340b15232139b3c43fcde5973e7fad30John Thompson
77935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
78035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
78135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
78235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
78335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
78435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
78535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
78635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
78735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
78835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
78935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
79035cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
79101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<RecordDecl>(d)) {
79235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
79335cc9627340b15232139b3c43fcde5973e7fad30John Thompson      << Attr.getName() << 9 /*class*/;
79435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
79535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
79635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
79735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  if (d->getAttr<VecReturnAttr>()) {
79835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
79935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
80035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
80135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
80201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  RecordDecl *record = cast<RecordDecl>(d);
80301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
80401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
80501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
80601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
80701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
80801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
80901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
81001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
81101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
81201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
81301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
81401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
81501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  for (RecordDecl::field_iterator iter = record->field_begin(); iter != record->field_end(); iter++) {
81601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
81701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
81801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
81901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
82001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
82101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
82201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
823cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
82435cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
82535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
826bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
827bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
828bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
82904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall      << Attr.getName() << 8 /*function, method, or parameter*/;
830bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
831bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
832bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
833bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
834bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
83573798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
83673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
83773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
8383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
83973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
84073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
841bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
842aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall  if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) &&
843aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall      !isa<TypeDecl>(d)) {
844fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8455dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
84673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
84773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
848bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
849cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
85073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
85173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
852b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
853b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
854b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (Attr.getNumArgs() != 0) {
855b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
856b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
857b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
858bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
859b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
860186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
861b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
862b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
863b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
864b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  } else if (!isFunctionOrMethod(d)) {
865b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8665dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
867b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
868b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
869bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
870cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
871b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
872b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
8733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
8753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
876fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
877fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0 or 1";
8783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
879bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
8803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
8813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
8823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
8833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
8843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
885ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
886ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
887fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
8883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
8893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
8903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
8913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
8923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
893bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
894c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
895fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8965dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
8973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
8983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
8993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
900cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority));
9013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
9023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
9053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
906fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
907fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner       << "0 or 1";
9083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
909bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
9103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
9123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
9133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
9143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
915ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
916ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
917fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
9183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
9193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
9203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
9213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
9223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
923bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
9246782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
925fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9265dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
9273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
9283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
9293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
930cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority));
9313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
9323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
933803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
935c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  int noArgs = Attr.getNumArgs();
936c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  if (noArgs > 1) {
937c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    S.Diag(Attr.getLoc(),
938c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian           diag::err_attribute_wrong_number_arguments) << "0 or 1";
939c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
940c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
941c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
942c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  StringLiteral *SE;
943c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  if (noArgs == 1) {
944c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
945c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    SE = dyn_cast<StringLiteral>(ArgExpr);
946c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
947c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      S.Diag(ArgExpr->getLocStart(),
948c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian             diag::err_attribute_not_string) << "deprecated";
949c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
950c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
9516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
952c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
953c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    SE = StringLiteral::CreateEmpty(S.Context, 1);
954bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
955c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context,
956c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                              SE->getString()));
9576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
959bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
960bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  // check the attribute arguments.
961c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  int noArgs = Attr.getNumArgs();
962c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  if (noArgs > 1) {
963c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << "0 or 1";
964bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
965bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
966c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
967c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  StringLiteral *SE;
968c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  if (noArgs == 1) {
969c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
970c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    SE = dyn_cast<StringLiteral>(ArgExpr);
971c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
972c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      S.Diag(ArgExpr->getLocStart(),
973c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
974c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
975c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
976c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
977c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  else
978c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    SE = StringLiteral::CreateEmpty(S.Context, 1);
979c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context,
980c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian                                               SE->getString()));
981bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
982bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
983803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
985545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
9863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
9876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
990545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
9916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
9926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
993bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
9946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
995fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
9963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
9976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
999bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1000c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  llvm::StringRef TypeStr = Str->getString();
1001cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1002bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1003c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1004cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1005c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1006cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1007c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1008cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1009c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1010cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
10116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
101208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
10136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1015bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1016cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
10176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10190db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
10200db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner                                    Sema &S) {
10210db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
10220db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
10230db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
10240db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1025bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10260db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
10270db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
10280db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
10290db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
10300db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1031bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1032cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
10330db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
10340db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
10350db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
1036fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
10372b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1038fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1039fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
10400db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
1041fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1042fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
10436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1044fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1045fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1046fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1047fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1048cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1049fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1050fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1051bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
1052f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1053f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
10542b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1055f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1056f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1057f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1058f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1059f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1060f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1061f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1062f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1063cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1064f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1065f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
10669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1067bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1068fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
10693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
10709eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
10719eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1072bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10739eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
10743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
10759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
10769eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1077bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1078cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
107992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
10809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
10819eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1082fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
10833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
10849eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
10859eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1086bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1087cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
10889eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
10899eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
1090770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1091770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1092770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1093fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1094fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0, 1 or 2";
1095770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1096bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1097bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1098770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1099770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
1100770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(0));
1101770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1102ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1103ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1104fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1106770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1107770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1108770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1109bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1110770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1111fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1112fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1113770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1114770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1115770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1116770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1117770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1118770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
1119770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(1));
1120770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1121ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1122ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1123fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11243c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1125770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1126770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1127770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1128bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1129770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1130770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1131770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1132fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1133fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1134770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1135770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1136770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1137770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1138770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
1139183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1140897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1141bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1142897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1143897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1144897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1145897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1146bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1147897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
11483bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1149770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1150bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
1151770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
1152770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
11533bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1154770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
11552f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
11562f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (isa<BlockDecl>(d)) {
1157bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1158bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
11592f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
11602f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
11612f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1162daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
1163bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
1164183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
11652f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
11663bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
11673bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
11682f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
11692f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1170ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
11712f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1172ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
11732f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
11742f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1175770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1176fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1177ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
1178770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1179770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1180cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos));
1181770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1182770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1183026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
1184026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
1185026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
1186026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1187026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1188026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1189026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1190f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1191026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
11925dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
1193026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1194026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1195bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1196f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1197f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1198f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1199f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1200f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1201f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1202f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1203f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1204f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1205f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1206f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1207f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1208cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1209026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1210026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1211026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
12126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1213545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
12143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
12156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12176e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1218f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  /* weak only applies to non-static declarations */
121911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (isStaticVarOrStaticFunciton(D)) {
1220f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) <<
1221f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian      dyn_cast<NamedDecl>(D)->getNameAsString();
1222f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1223f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1224f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
12256e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // TODO: could also be applied to methods?
12266e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
12276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
12285dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
12296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
12306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1231bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1232cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
12336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
12366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
12376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
12386e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
12396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
1240bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
12416e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
12426e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
12436e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
12446e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
12456e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    isDef = (!VD->hasExternalStorage() || VD->getInit());
12466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
124706a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis    isDef = FD->hasBody();
1248d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian  } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
1249d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian    // We ignore weak import on properties and methods
12501c90f4dc686ab872013544664c797604a309c563Mike Stump    return;
12515f8f8571c52dbf12fdefb15d2fedbcccb212c15cFariborz Jahanian  } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) {
1252c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian    // Don't issue the warning for darwin as target; yet, ignore the attribute.
12533be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian    if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin ||
1254c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian        !isa<ObjCInterfaceDecl>(D))
1255c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
12563be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian        << Attr.getName() << 2 /*variable and function*/;
12573be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian      return;
12586e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
12596e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
12606e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // Merge should handle any subsequent violations.
12616e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (isDef) {
1262bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
12636e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar           diag::warn_attribute_weak_import_invalid_on_definition)
12646e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar      << "weak_import" << 2 /*variable and function*/;
12656e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
12666e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
12676e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1268cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
12696e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
12706e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
12716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
12726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                    Sema &S) {
12736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
12746f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  if (Attr.getNumArgs() != 3) {
12752b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
12776f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
12786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
12796f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
12806f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
12816f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    Expr *E = static_cast<Expr *>(Attr.getArg(i));
12826f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1283ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1284ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
12856f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
12866f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
12876f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
12886f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
12896f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
12906f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1291cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1292cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
12936f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
12946f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
12956f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
1296026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
129717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
129817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
129917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
130017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
130117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
130217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
130317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
130417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
1305797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
1306797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
130717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1308797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
130917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
131017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
13111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1312797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1313bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1314a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1315a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1316a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1317797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1318797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
13191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1320a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1321a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1322a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1323a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1324a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1325a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1326cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString()));
132717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
132817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
13296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1330803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
13316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1332545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
13333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
13346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1336bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1337cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
13386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1340232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1341232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1342232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
13433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1344232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1345232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1346bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1347cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1348232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1349232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1350232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1351232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1352232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
13533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1354232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1355232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1356bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1357cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1358232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1359232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1360f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1361bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1362f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1363f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1364f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1365bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1366f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1367f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1368f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1369f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1370bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1371f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
1372bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1373f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1374f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1375f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1376f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1377bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1378f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1379c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1380c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: The lookup source location should be in the attribute, not the
1381c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // start of the attribute.
1382f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1383c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor    = S.LookupSingleName(S.TUScope, Attr.getParameterName(), Attr.getLoc(),
1384f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall                         Sema::LookupOrdinaryName);
1385f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
138689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1387f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1388f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1389f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1390bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1391f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1392f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
139389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
1394f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1395f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1396f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1397f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1398f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
139989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
1400f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1401f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1402f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1403bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
140489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
140589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
140689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
140789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
14081c23e91ef66688d20868b6bab3b5589a119eb603John McCall  if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
1409bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
141089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
141189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
141289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
141389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1414bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1415cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1416f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1417f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1418bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1419bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1420bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
14215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Attr.getNumArgs() != 1) {
14225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
14235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
14245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
14255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
14265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
14275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << Attr.getName() << 0 /*function*/;
14285b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
14295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
143007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
143107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
143207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
143307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
143407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
14355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
143607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
14375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
14385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
14395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1440ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1441ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
14425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
14445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
14455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1446bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
14485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
14495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
14505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
14515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1452bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1454bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
145507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
145607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
145707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
145807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
145907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
146007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
146107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
146207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
146307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
14645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
14655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1466bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
14685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
14695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
14705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
14716217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
14725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
14735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1474bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
14755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
14765b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1477bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Ty = getFunctionOrMethodResultType(d);
14795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
14805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
14815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
14826217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
14835b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
14845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1485bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
14865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
14875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1488bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
149007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
149107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
14925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
14935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
14942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
14952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
14962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
14972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
14982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
14993c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
15002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
15012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
15022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
15032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
15042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
15052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
15062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
15072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
15082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
15092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
15102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
15112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
15122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
15132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
15142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
15152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
15162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
15172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
15182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "zcmn_err")
15192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
15202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1521bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1522bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
15233c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
15243c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
15252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
15262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
15272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1528521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
1529521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
1530521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
1531521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian                                   Sema &S) {
1532521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
1533521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1534521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1535521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1536521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1537b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) {
1538b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1539b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1540b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1541b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1542b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  QualType T = dyn_cast<VarDecl>(d)->getType();
1543b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
1544b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
1545b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
1546b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1547b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1548b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1549b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1550b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1551521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
1552521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1553521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1554521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1555521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1556521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  Expr *priorityExpr = static_cast<Expr *>(Attr.getArg(0));
1557b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1558521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
1559521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1560521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1561521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1562521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
1563521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1564521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1565521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
15669f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
1567521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
1568521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1569521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
1570521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1571521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1572521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1573cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum));
1574521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
1575521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1576bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1577bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1578803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
15796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1580545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1581fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
15823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
15836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
15856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1586545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
15873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
15886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
15906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1591620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1592fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
15935dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
15946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
15966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
159707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
159807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
159907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
160007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
16016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
16026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
160301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Format = Attr.getParameterName()->getName();
16046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
16062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
16072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
16082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
16092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
16102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
16113c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
16123c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
16133c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
16143c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
16152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1616fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
161701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
16186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
1622545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1623803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1624ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1625ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1626fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
16273c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
16286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1632fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
16333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
16346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
16386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1639bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16404a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
16414a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
164207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
164307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
164407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
16454a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
16464a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
16474a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
16484a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
16491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
16513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
16526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16532b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1654085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1655fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1656fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1657085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1658085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
16592b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1660390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1661390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1662803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1663390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1664fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1665fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
16666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1667bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
16686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
16696217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1670390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1671fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1672fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
16736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
1677545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1678803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1679ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1680ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1681fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
16823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
16836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
16876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
16883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
16896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
16906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1691803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
16926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
16936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
16946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
16973c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
16982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
16996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1700fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1701fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
17026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
17036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
17046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
17056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1706fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
17073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
17086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1711cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1712cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
17132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
17146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17160b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
17170b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
17186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1719545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
17203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
17216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
17250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
1726bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
17270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
17280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
17290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
17300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = dyn_cast<RecordDecl>(d);
17310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
17320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1733fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
17345dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 1 /*union*/;
17356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1739bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
17400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
17410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
17420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
17430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
174417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
174517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
17460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
17470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
17480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
17490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1750bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
17510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
17520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
175390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
1754bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
175590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
175690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
17570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
17580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1759bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
17600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
17610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
17620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
17630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
17640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
17650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
17660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
17670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1768bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
17690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
1770bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
17710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
17720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
17730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1774bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
17750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
17760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
1777bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1778bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1779bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
17806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1781cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
17826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17840b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
17856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1786545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
17873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
17886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1790797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
1791797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1792bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
17946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
17956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
1796797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
17976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1799cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString()));
18006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
18016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18024ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
18036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1804545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
18053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
18066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1808bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1809bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
1810bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
1811bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
18126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1813545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
1814cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
18154ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
18164ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
18174ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
18184ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  S.AddAlignedAttr(Attr.getLoc(), D, static_cast<Expr *>(Attr.getArg(0)));
18194ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
18204ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
18214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
18224ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
18234ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
1824cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
18256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1827bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1828cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
182949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
18304ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
18314ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
18324ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
183349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
183449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
1835396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
18364ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
18374ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
1838396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
1839396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
1840396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
1841cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
1842cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
1843cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1844cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
1845cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
1846cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
1847cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
1848cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
18496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1850fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1851bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive
1852bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
1853fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
1854bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
1855bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
1856bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
18570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1858fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
1859fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
1860fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1861fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
1862fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
18633c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1864fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1865fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1866fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1867fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
1868fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
18690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1870fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1871fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1872210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
187301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Str = Attr.getParameterName()->getName();
1874fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1875fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
1876210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
1877210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
1878fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1879fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1880fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
188173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
1882210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
1883fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
188473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
188573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
188673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
188773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
188873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
188973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
189073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
189173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
189273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
189373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
189473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
189573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
189673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
189773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
189873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
189973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1900fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1901fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1902fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1903fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1904210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
19050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1906210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
19070b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1908fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1909fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
1910210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
19110b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1912fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1913fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1914fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1915fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
1916fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1917fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
1918fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1919fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
1920fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
1921fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1922fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1923fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1924fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
192573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1926183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
192773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
192873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
19292ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
193073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
193173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
193273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
193373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
193473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
193573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
193673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
193773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
193873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1939390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
1940390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
1941390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
1942390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
1943f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
1944f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
1945fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
1946fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
1947fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
19483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1949fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1950fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
19513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1952fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1953fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
195473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
195573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
195673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
195773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1958fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
19590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
1960fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
19610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
1962fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1963fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
196473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
196573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
196673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
196773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1968fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
19690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
1970fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
19710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
1972fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1973fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
1974fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
19750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
1976fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
19770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
1978fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
19790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
1980fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1981fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
1982fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
19830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
1984fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
1985aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
1986aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
1987aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
1988aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
1989fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
1990aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
1991aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
1992aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
1993aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
1994fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
199573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
199673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
199773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1998f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
1999f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2000f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2001f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2002f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2003f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2004f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2005f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2006f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
200773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2009fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
201073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
201173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2012fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2013fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2014fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2015ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
2016ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2017a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2018ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2019fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2020fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
20210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
20221feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2023d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
2024d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
2025d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2026d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2027d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2028e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
20295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (!isFunctionOrMethod(d)) {
2030d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
20315dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
2032d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2033d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2034bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2035cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2036d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2037d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
20381feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
20395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
20405bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
20415bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
20425bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
20435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2044bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2045c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
20465bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
20475dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
20485bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
20495bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2050bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2051cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
20525bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
20535bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
20547255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
20557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner                                           Sema &S) {
20567255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
20577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (Attr.getNumArgs() != 0) {
20587255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
20597255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
20607255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
20617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
20627255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (!isa<FunctionDecl>(d)) {
20637255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
20647255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    << Attr.getName() << 0 /*function*/;
20657255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
20667255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
20677255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2068cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context));
20697255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
20707255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2071cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
207226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
207326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
207426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
207526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
207626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2077bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2078c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
2079c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
208026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
20815dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
208226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
208326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2084bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20850130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2086cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2087c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2088c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2089bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2090cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
209126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
209226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
2093e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnarastatic void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2094e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2095e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2096e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  assert(Attr.isInvalid() == false);
2097e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2098e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  switch (Attr.getKind()) {
2099e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
2100cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2101e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2102e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
2103cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2104e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2105f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
2106cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
210704633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2108e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
2109cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2110e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
211152fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
211252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    d->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
211352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2114e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2115e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2116e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2117e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2118e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2119e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2120ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2121ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  // check the attribute arguments.
2122ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (Attr.getNumArgs() != 1) {
212355d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2124ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2125ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
212655d3aaf9a537888734762170823daf750ea9036dEli Friedman
2127ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (!isFunctionOrMethod(d)) {
2128ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
21295dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
2130ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2131ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
213255d3aaf9a537888734762170823daf750ea9036dEli Friedman
213355d3aaf9a537888734762170823daf750ea9036dEli Friedman  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
213455d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2135ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2136ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
213755d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
213855d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
213955d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
214055d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
214155d3aaf9a537888734762170823daf750ea9036dEli Friedman
2142264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov  if (S.Context.Target.getRegParmMax() == 0) {
2143264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
214455d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
214555d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
214655d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
214755d3aaf9a537888734762170823daf750ea9036dEli Friedman
2148348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
2149264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2150264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
215155d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
215255d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
215355d3aaf9a537888734762170823daf750ea9036dEli Friedman
2154cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context,
2155cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           NumParams.getZExtValue()));
2156ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2157ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
2158bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2159bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // check the attribute arguments.
2160bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Attr.getNumArgs() != 0) {
2161bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2162bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
2163bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2164bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2165bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isa<CXXRecordDecl>(d)
2166bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt   && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) {
2167bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(),
2168bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
2169bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                   : diag::warn_attribute_wrong_decl_type)
2170bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      << Attr.getName() << 7 /*virtual method or class*/;
2171bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
2172bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
21737725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21747725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
21757725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21767725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<FinalAttr>()) {
21777725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final";
21787725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
21797725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
2180bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2181cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context));
2182bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2183bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
21840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
21857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt// C++0x member checking attributes
21867725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===//
21877725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21887725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) {
21897725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
21907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
21917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
21927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
21937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21947725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<CXXRecordDecl>(d)) {
21957725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
21967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
21977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
21987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 9 /*class*/;
21997725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
22007725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
22017725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
22027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<BaseCheckAttr>()) {
22037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check";
22047725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
22057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
22067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
2207cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context));
22087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
22097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
22107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
22117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
22127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
22137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
22147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
22157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
22167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<RecordDecl>(d->getDeclContext())) {
22177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    // FIXME: It's not the type that's the problem
22187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
22197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
22207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
22217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 11 /*member*/;
22227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
22237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
22247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
22257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
22267725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
22277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<HidingAttr>()) {
22287725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding";
22297725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
22307725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
22317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
2232cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context));
22337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
22347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
22357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
22367725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
22377725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
22387725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
22397725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
22407725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
22417725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) {
22427725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    // FIXME: It's not the type that's the problem
22437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
22447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
22457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
22467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 10 /*virtual method*/;
22477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
22487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
22497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
22507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
22517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
22527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<OverrideAttr>()) {
22537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override";
22547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
22557725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
22567725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
2257cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context));
22587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
22597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
22607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===//
2261b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
2262b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
2263b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2264b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
2265b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek                                        Sema &S) {
2266b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
22675dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  QualType RetTy;
2268bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22695dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
22705dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = MD->getResultType();
22715dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
22725dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = FD->getResultType();
22735dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
227421531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    SourceLocation L = Attr.getLoc();
227521531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
227621531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek        << SourceRange(L, L) << Attr.getName() << 3 /* function or method */;
2277b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
2278b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
2279bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22806217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>()
2281183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        || RetTy->getAs<ObjCObjectPointerType>())) {
228221531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    SourceLocation L = Attr.getLoc();
228321531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
228421531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek      << SourceRange(L, L) << Attr.getName();
2285bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
22865dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
2287bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2288b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  switch (Attr.getKind()) {
2289b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
2290b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
2291b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
229231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
2293cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
229431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
229531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
2296cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
229731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
2298b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
2299cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context));
2300b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2301b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
2302cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context));
2303b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2304b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
2305b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
2306b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2307f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2308f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
2309f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis         Attr.getKind() == AttributeList::AT_dllexport;
2310f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
2311f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
2312b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
23130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
23140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
23150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
2316a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
2317803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
2318bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
2319bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
2320bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D,
2321bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump                                 const AttributeList &Attr, Sema &S) {
2322e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  if (Attr.isInvalid())
2323e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2324e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2325f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
2326f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis    // FIXME: Try to deal with other __declspec attributes!
2327290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman    return;
2328803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
232963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  case AttributeList::AT_IBAction:            HandleIBAction(D, Attr, S); break;
2330857e918a8a40deb128840308a318bf623d68295fTed Kremenek    case AttributeList::AT_IBOutlet:          HandleIBOutlet(D, Attr, S); break;
2331857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
2332857e918a8a40deb128840308a318bf623d68295fTed Kremenek      HandleIBOutletCollection(D, Attr, S); break;
2333803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
2334ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
23356e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
23364211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
23374211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
2338bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
2339bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
2340803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
23417725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_alias:       HandleAliasAttr       (D, Attr, S); break;
23427725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_aligned:     HandleAlignedAttr     (D, Attr, S); break;
2343bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
2344af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
2345b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
2346bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
23477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_annotate:    HandleAnnotateAttr    (D, Attr, S); break;
23487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_base_check:  HandleBaseCheckAttr   (D, Attr, S); break;
2349bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
23507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                      HandleDependencyAttr  (D, Attr, S); break;
23517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
23527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_deprecated:  HandleDeprecatedAttr  (D, Attr, S); break;
23537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_destructor:  HandleDestructorAttr  (D, Attr, S); break;
23543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
23559cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    HandleExtVectorTypeAttr(scope, D, Attr, S);
23563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
23577725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_final:       HandleFinalAttr       (D, Attr, S); break;
23587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format:      HandleFormatAttr      (D, Attr, S); break;
23597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format_arg:  HandleFormatArgAttr   (D, Attr, S); break;
23607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr   (D, Attr, S); break;
23617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_hiding:      HandleHidingAttr      (D, Attr, S); break;
23627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_mode:        HandleModeAttr        (D, Attr, S); break;
23637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_malloc:      HandleMallocAttr      (D, Attr, S); break;
23647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nonnull:     HandleNonNullAttr     (D, Attr, S); break;
2365dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
2366dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
2367dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
2368dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      HandleOwnershipAttr     (D, Attr, S); break;
2369dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  case AttributeList::AT_naked:       HandleNakedAttr       (D, Attr, S); break;
23707725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;
23717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;
23727725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_override:    HandleOverrideAttr    (D, Attr, S); break;
237335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  case AttributeList::AT_vecreturn:   HandleVecReturnAttr   (D, Attr, S); break;
2374b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2375b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
237631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
237731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
2378b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
2379b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
2380b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    HandleNSReturnsRetainedAttr(D, Attr, S); break;
2381b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
23826f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
23836f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    HandleReqdWorkGroupSize(D, Attr, S); break;
23846f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
2385521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
2386521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      HandleInitPriorityAttr(D, Attr, S); break;
2387521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
23887725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_packed:      HandlePackedAttr      (D, Attr, S); break;
23897725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_section:     HandleSectionAttr     (D, Attr, S); break;
23907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
23917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unused:      HandleUnusedAttr      (D, Attr, S); break;
23927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_used:        HandleUsedAttr        (D, Attr, S); break;
23937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_visibility:  HandleVisibilityAttr  (D, Attr, S); break;
2394026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
2395026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
23967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak:        HandleWeakAttr        (D, Attr, S); break;
239711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  case AttributeList::AT_weakref:     HandleWeakRefAttr     (D, Attr, S); break;
23987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak_import: HandleWeakImportAttr  (D, Attr, S); break;
2399803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
2400803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
2401803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
24020db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
24030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
24040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
2405f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
24067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nsobject:    HandleObjCNSObject    (D, Attr, S); break;
24077725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_blocks:      HandleBlocksAttr      (D, Attr, S); break;
24087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_sentinel:    HandleSentinelAttr    (D, Attr, S); break;
24097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_const:       HandleConstAttr       (D, Attr, S); break;
24107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_pure:        HandlePureAttr        (D, Attr, S); break;
24117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_cleanup:     HandleCleanupAttr     (D, Attr, S); break;
24127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nodebug:     HandleNoDebugAttr     (D, Attr, S); break;
24137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noinline:    HandleNoInlineAttr    (D, Attr, S); break;
24147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_regparm:     HandleRegparmAttr     (D, Attr, S); break;
2415bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
241605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
241705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
24187255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
24197255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    HandleNoInstrumentFunctionAttr(D, Attr, S);
24207255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
242104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
242204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
242304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
2424f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
242552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2426e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    HandleCallConvAttr(D, Attr, S);
242704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
2428803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
242982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
243082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
243182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
24327d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
24337d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
2434803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
2435803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2436803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2437803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
2438803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
2439803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
24409cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) {
244111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
244211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    ProcessDeclAttribute(S, D, *l, *this);
244311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
244411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
244511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
244611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
244711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
244811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
244911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
2450dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
245111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
2452803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2453803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2454803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
2455e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
2456e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
24571eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
24587b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
2459e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
2460e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
2461e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
2462e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
2463a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
2464b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
2465b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
2466b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange());
2467b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
2468e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
2469e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
2470e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                           VD->getLocation(), II,
2471a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
247216573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
247316573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
2474b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
2475b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
2476b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange());
2477b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
2478e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2479e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
2480e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
2481e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
2482e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
2483e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
24847b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
2485c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
2486c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
2487c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
2488c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
2489c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
2490cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
2491cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
2492cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
2493c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
2494c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
2495c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
2496c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
2497c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
2498c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
2499c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
2500c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
2501cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
2502e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2503e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
2504e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
25050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
25060744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
25070744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
25089cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
2509d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
2510d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
2511d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  if (!WeakUndeclaredIdentifiers.empty()) {
2512d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall    if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
2513d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall      if (IdentifierInfo *Id = ND->getIdentifier()) {
2514d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
2515d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          = WeakUndeclaredIdentifiers.find(Id);
2516d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
2517d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakInfo W = I->second;
2518d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          DeclApplyPragmaWeak(S, ND, W);
2519d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakUndeclaredIdentifiers[Id] = W;
2520d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
2521e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
2522e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
2523e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2524e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
25250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
25260744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
25279cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
2528bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25290744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
25300744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
25310744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
25320744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
25330744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
25340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
25359cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      ProcessDeclAttributeList(S, D, Attrs);
2536bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25370744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
25380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
25399cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
25400744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
254154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
254254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// PushParsingDeclaration - Enter a new "scope" of deprecation
254354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// warnings.
254454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall///
254554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// The state token we use is the start index of this scope
254654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// on the warning stack.
2547f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallSema::ParsingDeclStackState Sema::PushParsingDeclaration() {
254854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclDepth++;
25492f514480c448708ec382a684cf5e035d3a827ec8John McCall  return (ParsingDeclStackState) DelayedDiagnostics.size();
255054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
255154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
2552d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) {
255354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
255454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclDepth--;
255554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
25562f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (DelayedDiagnostics.empty())
255754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
255854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
255954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  unsigned SavedIndex = (unsigned) S;
25602f514480c448708ec382a684cf5e035d3a827ec8John McCall  assert(SavedIndex <= DelayedDiagnostics.size() &&
256154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall         "saved index is out of bounds");
256254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
256358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  unsigned E = DelayedDiagnostics.size();
256458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
25652f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
25662f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
25672f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (D) {
25682f514480c448708ec382a684cf5e035d3a827ec8John McCall    // We really do want to start with 0 here.  We get one push for a
25692f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
25702f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
25712f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
25722f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
25732f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
257458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    for (unsigned I = 0; I != E; ++I) {
25752f514480c448708ec382a684cf5e035d3a827ec8John McCall      if (DelayedDiagnostics[I].Triggered)
25762f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
25772f514480c448708ec382a684cf5e035d3a827ec8John McCall
25782f514480c448708ec382a684cf5e035d3a827ec8John McCall      switch (DelayedDiagnostics[I].Kind) {
25792f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
25802f514480c448708ec382a684cf5e035d3a827ec8John McCall        HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D);
25812f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
25822f514480c448708ec382a684cf5e035d3a827ec8John McCall
25832f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
25842f514480c448708ec382a684cf5e035d3a827ec8John McCall        HandleDelayedAccessCheck(DelayedDiagnostics[I], D);
25852f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
258654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
258754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
258854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
258954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
259058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
259158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  for (unsigned I = SavedIndex; I != E; ++I)
259258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    DelayedDiagnostics[I].destroy();
259358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
25942f514480c448708ec382a684cf5e035d3a827ec8John McCall  DelayedDiagnostics.set_size(SavedIndex);
25952f514480c448708ec382a684cf5e035d3a827ec8John McCall}
25962f514480c448708ec382a684cf5e035d3a827ec8John McCall
25972f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
25982f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
25992f514480c448708ec382a684cf5e035d3a827ec8John McCall    if (D->hasAttr<DeprecatedAttr>())
26002f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
26012f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
26022f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
26032f514480c448708ec382a684cf5e035d3a827ec8John McCall}
26042f514480c448708ec382a684cf5e035d3a827ec8John McCall
26059c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
26062f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
26072f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
26082f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
26092f514480c448708ec382a684cf5e035d3a827ec8John McCall
26102f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
2611ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
2612c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
2613ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
2614ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
2615c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
2616c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
2617ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
261854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
261954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
2620ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramervoid Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
2621c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                  SourceLocation Loc) {
262254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
262354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (ParsingDeclDepth) {
2624c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D,
2625c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                                                    Message));
262654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
262754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
262854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
262954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
263054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
263154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
2632ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
2633c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
2634c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
2635c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
2636c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated) << D->getDeclName();
263754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
2638