SemaDeclAttr.cpp revision 8e5fc9be37c6828ad008f22730e3baac1bef1686
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    }
2007a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = 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.
3457a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *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?
374de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor    QualType T = getFunctionOrMethodArgType(d, x).getNonReferenceType();
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) {
389de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor      QualType T = getFunctionOrMethodArgType(d, I).getNonReferenceType();
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
4917a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *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?
5357a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = 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) {
6437a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = 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?
654f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher    d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
655f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
65611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
65711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
658cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
65911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
66011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
661803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
663545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
6643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
6656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
667bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6687a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
671bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
673fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
6743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
6756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
677bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
678f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  if (S.Context.Target.getTriple().getOS() == llvm::Triple::Darwin) {
679f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
680f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
681f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
682f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
6836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
684bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
685f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
686f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
689dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbarstatic void HandleNakedAttr(Decl *d, const AttributeList &Attr,
690dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar                                   Sema &S) {
691dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
692dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  if (Attr.getNumArgs() != 0) {
693dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
694dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
695dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
696dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
697dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  if (!isa<FunctionDecl>(d)) {
698dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
699dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar      << Attr.getName() << 0 /*function*/;
700dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
701dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
702dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
703dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
704dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
705dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
706bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
707af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
708dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
709af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
7103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
711af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
712af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
7135bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
714c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
7155bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
716dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar      << Attr.getName() << 0 /*function*/;
7175bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
7185bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
719bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
720cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
721af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
722af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
72376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
724dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
72576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  if (Attr.getNumArgs() != 0) {
72676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
72776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
72876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
7291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7302cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
7311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
7322cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
733cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
7342cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
7352cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
736fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
737fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
7382cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
73976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
74076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
74134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohmanstatic void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
74234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
74334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  if (Attr.getNumArgs() != 0) {
74434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
74534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
74634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  }
74734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
74834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
74934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
75034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
751a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
752a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
753722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  if (isa<VarDecl>(d))
754722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
755722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
756722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
757722109c1b7718d3e8aab075ce65007b372822199Eric Christopher      << Attr.getName() << 12 /* variable */;
758a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
759a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
760a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
761a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
762722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  if (isa<VarDecl>(d))
763722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
764722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
765722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
766722109c1b7718d3e8aab075ce65007b372822199Eric Christopher      << Attr.getName() << 12 /* variable */;
767a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
768a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
769b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
770b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
771b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  assert(Attr.isInvalid() == false);
772b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context));
773b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
774b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
775b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
776b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek                                       Sema &S) {
777b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
778b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
779b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
780b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
781545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
782e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
783b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek    return;
7846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
785b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
78619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
78719c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    ValueDecl *VD = dyn_cast<ValueDecl>(d);
7883ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
7893ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
790e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
791e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
792b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
793b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      << Attr.getName() << 0 /*function*/;
794b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
79519c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
7966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
797b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
798b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
7996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
80135cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
80235cc9627340b15232139b3c43fcde5973e7fad30John Thompsonstatic void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
80335cc9627340b15232139b3c43fcde5973e7fad30John Thompson                                       Sema &S) {
80435cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
80535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
80635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
807f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
808f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
809f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
810f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
811f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
81235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
81335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
81435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
81535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
81635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
81735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
81835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
81935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
82035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
82135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
82235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
82335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
82435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
82535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
82635cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
82701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<RecordDecl>(d)) {
82835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
82935cc9627340b15232139b3c43fcde5973e7fad30John Thompson      << Attr.getName() << 9 /*class*/;
83035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
83135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
83235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
83335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  if (d->getAttr<VecReturnAttr>()) {
83435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
83535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
83635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
83735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
83801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  RecordDecl *record = cast<RecordDecl>(d);
83901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
84001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
84101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
84201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
84301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
84401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
84501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
84601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
84701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
84801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
84901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
85001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
851f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
852f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
85301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
85401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
85501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
85601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
85701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
85801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
85901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
860cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
86135cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
86235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
863bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
864bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
865bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
86604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall      << Attr.getName() << 8 /*function, method, or parameter*/;
867bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
868bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
869bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
870bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
871bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
87273798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
87373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
87473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
8753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
87673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
87773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
878bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
879aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall  if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) &&
880aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall      !isa<TypeDecl>(d)) {
881fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8825dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
88373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
88473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
885bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
886cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
88773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
88873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
889b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
890b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
891b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (Attr.getNumArgs() != 0) {
892b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
893b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
894b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
895bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
896b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
897186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
898b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
899b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
900b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
901b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  } else if (!isFunctionOrMethod(d)) {
902b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9035dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
904b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
905b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
906bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
907cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
908b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
909b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
9103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
9123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
913fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
914fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0 or 1";
9153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
916bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
9173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
9193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
9207a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
9213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
922ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
923ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
924fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
9253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
9263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
9273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
9283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
9293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
930bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
931c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
932fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9335dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
9343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
9353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
9363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
937f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
938f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
9393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
9403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
9433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
944fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
945fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner       << "0 or 1";
9463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
947bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
9483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
9503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
9517a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
9523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
953ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
954ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
955fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
9563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
9573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
9583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
9593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
9603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
961bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
9626782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
963fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9645dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
9653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
9663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
9673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
968f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
969f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
9703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
9713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
972803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
974c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  int noArgs = Attr.getNumArgs();
975c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  if (noArgs > 1) {
976c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    S.Diag(Attr.getLoc(),
977c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian           diag::err_attribute_wrong_number_arguments) << "0 or 1";
978c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
979c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
980c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
981c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  StringLiteral *SE;
982c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  if (noArgs == 1) {
9837a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *ArgExpr = Attr.getArg(0);
984c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    SE = dyn_cast<StringLiteral>(ArgExpr);
985c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
986c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      S.Diag(ArgExpr->getLocStart(),
987c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian             diag::err_attribute_not_string) << "deprecated";
988c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
989c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
9906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
991c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
992c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    SE = StringLiteral::CreateEmpty(S.Context, 1);
993bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
994c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context,
995c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                              SE->getString()));
9966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
998bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
999bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  // check the attribute arguments.
1000c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  int noArgs = Attr.getNumArgs();
1001c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  if (noArgs > 1) {
1002f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher    S.Diag(Attr.getLoc(),
1003f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher           diag::err_attribute_wrong_number_arguments) << "0 or 1";
1004bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1005bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1006c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
1007c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  StringLiteral *SE;
1008c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  if (noArgs == 1) {
10097a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *ArgExpr = Attr.getArg(0);
1010c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    SE = dyn_cast<StringLiteral>(ArgExpr);
1011c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1012c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      S.Diag(ArgExpr->getLocStart(),
1013c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1014c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1015c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1016c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1017c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  else
1018c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    SE = StringLiteral::CreateEmpty(S.Context, 1);
1019c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context,
1020c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian                                               SE->getString()));
1021bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1022bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1023803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
10246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1025545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
10263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
10276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1029bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10307a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
10316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
10326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1033bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
1035fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
10363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
10376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1039bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1040c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  llvm::StringRef TypeStr = Str->getString();
1041cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1042bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1043c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1044cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1045c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1046cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1047c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1048cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1049c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1050cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
10516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
105208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
10536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1055bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1056cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
10576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10590db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
10600db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner                                    Sema &S) {
10610db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
10620db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
10630db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
10640db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1065bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10660db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
10670db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
10680db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
10690db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
10700db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1071bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1072cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
10730db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
10740db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
10750db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
1076fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
10772b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1078fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1079fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
10800db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
1081fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1082fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
10836217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1084fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1085fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1086fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1087fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1089fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1090fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1091bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
1092f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1093f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
10942b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1095f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1096f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1097f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1098f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1099f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1100f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1101f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1102f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1103cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1104f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1105f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
11069eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1107bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1108fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
11093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
11109eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
11119eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1112bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11139eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
11143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11159eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
11169eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1117bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1118cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
111992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
11209eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
11219eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1122fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
11233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
11249eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
11259eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1126bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1127cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
11289eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
11299eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
1130770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1131770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1132770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1133fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1134fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0, 1 or 2";
1135770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1136bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1137bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1138770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1139770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
11407a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1141770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1142ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1143ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1144fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1146770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1147770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1148770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1149bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1150770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1151fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1152fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1153770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1154770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1155770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1156770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1157770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1158770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
11597a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1160770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1161ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1162ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1163fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1165770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1166770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1167770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1168bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1169770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1170770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1171770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1172fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1173fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1174770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1175770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1176770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1177770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1178770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
1179183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1180897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1181bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1182897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1183897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1184897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1185897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1186bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1187897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
11883bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1189770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
1191770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
1192770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
11933bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1194770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
11952f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
11962f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (isa<BlockDecl>(d)) {
1197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1198bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
11992f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
12002f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
12012f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1202daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
1203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
1204f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
12052f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
12063bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
12073bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
12082f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
12092f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1210ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
12112f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1212ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
12132f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
12142f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1215770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1216fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1217ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
1218770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1219770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1220f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1221f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1222770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1223770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1224026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
1225026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
1226026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
1227026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1228026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1229026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1230026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1231f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1232026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
12335dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
1234026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1235026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1236bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1237f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1238f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1239f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1240f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1241f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1242f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1243f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1244f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1245f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1246f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1247f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1248f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1249cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1250026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1251026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1252026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
12536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1254545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
12553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
12566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12586e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1259f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  /* weak only applies to non-static declarations */
126011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (isStaticVarOrStaticFunciton(D)) {
1261f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) <<
1262f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian      dyn_cast<NamedDecl>(D)->getNameAsString();
1263f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1264f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1265f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
12666e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // TODO: could also be applied to methods?
12676e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
12686e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
12695dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
12706e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
12716e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1272bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1273cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
12746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12766e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
12776e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
12786e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
12796e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
12806e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
1281bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
12826e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
12836e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
12846e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
12856e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
12866e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    isDef = (!VD->hasExternalStorage() || VD->getInit());
12876e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
128806a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis    isDef = FD->hasBody();
1289d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian  } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
1290d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian    // We ignore weak import on properties and methods
12911c90f4dc686ab872013544664c797604a309c563Mike Stump    return;
12925f8f8571c52dbf12fdefb15d2fedbcccb212c15cFariborz Jahanian  } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) {
1293c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian    // Don't issue the warning for darwin as target; yet, ignore the attribute.
12943be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian    if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin ||
1295c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian        !isa<ObjCInterfaceDecl>(D))
1296c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
12973be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian        << Attr.getName() << 2 /*variable and function*/;
12983be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian      return;
12996e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
13006e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
13016e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // Merge should handle any subsequent violations.
13026e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (isDef) {
1303bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
13046e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar           diag::warn_attribute_weak_import_invalid_on_definition)
13056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar      << "weak_import" << 2 /*variable and function*/;
13066e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
13076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
13086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1309cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
13106e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
13116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
13126f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
13136f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                    Sema &S) {
13146f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
13156f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  if (Attr.getNumArgs() != 3) {
13162b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
13176f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
13186f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
13196f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
13206f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
13216f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
13227a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
13236f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1324ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1325ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
13266f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
13276f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
13286f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
13296f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
13306f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
13316f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1332cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1333cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
13346f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
13356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
13366f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
1337026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
133817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
133917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
134017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
134117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
134217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
134317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
134417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
134517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
13467a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1347797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
134817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1349797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
135017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
135117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
13521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1353797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1354bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1355a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1356a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1357a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1358797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1359797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
13601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1361a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1362a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1363a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1364a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1365a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1366a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1367f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1368f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
136917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
137017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
13716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1372803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
13736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1374545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
13753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
13766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1378bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1379cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
13806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1382232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1383232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1384232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
13853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1386232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1387232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1388bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1389cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1390232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1391232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1392232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1393232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1394232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
13953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1396232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1397232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1398bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1399cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1400232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1401232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1402f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1403bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1404f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1405f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1406f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1407bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1408f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1409f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1410f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1411f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1412bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1413f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
1414bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1415f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1416f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1417f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1418f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1419bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1420f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1421c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1422f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1423f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1424f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1425f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
1426f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1427f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1428f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1429f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1430bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1431f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1432f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
1433f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1434f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
1435f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1436f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1437f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1438f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1439f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
1440f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1441f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
1442f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1443f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1444f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1445bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
144689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
144789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
144889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
144989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
14501c23e91ef66688d20868b6bab3b5589a119eb603John McCall  if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
1451f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
145289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
145389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
145489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
145589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1456bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1457cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1458223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1459f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1460f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1461bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1462bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1463bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
14645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Attr.getNumArgs() != 1) {
14655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
14665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
14675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
14685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
14695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
14705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << Attr.getName() << 0 /*function*/;
14715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
14725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
147307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
147407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
147507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
147607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
147707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
14785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
147907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
14805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
14817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
14825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1483ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1484ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
14855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
14875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
14885b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
14915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
14925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
14935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
14945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1495bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1497bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
149807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
149907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
150007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
150107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
150207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
150307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
150407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
150507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
150607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
15075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
15085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1509bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
15115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
15125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
15135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
15146217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
15155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
15165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1517bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
15185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
15195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1520bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Ty = getFunctionOrMethodResultType(d);
15225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
15235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
15245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
15256217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
15265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
15275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1528bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
15295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
15305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1531bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1532bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
153307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
153407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
15355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
15365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
15372b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
15382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
15392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
15402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
15412b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
15423c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
15432b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
15442b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
15452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
15462b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
15472b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
15482b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
15492b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
15502b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
15512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
15522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
15532b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
15542b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
15552b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
15562b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
15572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
15582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
15592b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
15602b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
15612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "zcmn_err")
15622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
15632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1564bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1565bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
15663c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
15673c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
15682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
15692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
15702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1571521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
1572521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
1573521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
1574521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian                                   Sema &S) {
1575521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
1576521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1577521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1578521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1579521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1580b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) {
1581b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1582b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1583b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1584b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1585b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  QualType T = dyn_cast<VarDecl>(d)->getType();
1586b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
1587b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
1588b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
1589b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1590b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1591b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1592b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1593b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1594521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
1595521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1596521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1597521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1598521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
15997a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
1600b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1601521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
1602521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1603521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1604521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1605521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
1606521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1607521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1608521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
16099f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
1610521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
1611521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1612521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
1613521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1614521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1615521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1616f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
1617f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
1618521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
1619521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1620bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1621bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1622803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
16236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1624545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1625fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
16263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
16276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1630545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
16313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
16326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1635620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1636fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16375dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
16386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
164107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
164207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
164307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
164407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
16456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
16466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
164701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Format = Attr.getParameterName()->getName();
16486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
16502b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
16512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
16522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
16532b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
16542b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
16553c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
16563c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
16573c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
16583c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
16592b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1660fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
166101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
16626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
16667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
1667803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1668ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1669ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1670fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
16713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
16726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1676fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
16773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
16786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
16826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1683bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16844a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
16854a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
168607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
168707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
168807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
16894a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
16904a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
16914a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
16924a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
16931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
16953568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
16966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1698085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1699fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1700fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1701085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1702085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
17032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1704390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1705390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1706803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1707390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1708fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1709fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
17106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1711bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
17126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
17136217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1714390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1715fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1716fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
17176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
17217a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
1722803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1723ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1724ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1725fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
17263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
17276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
17316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
17323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
17336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
17346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1735803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
17366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
17376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
17386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
17413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
17422b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
17436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1744fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1745fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
17466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
17476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
17486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
17496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1750fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
17513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
17526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1755cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1756cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
17572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
17586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
17610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
17626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1763545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
17643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
17656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
17690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
1770bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
17710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
17720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
17730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
17740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = dyn_cast<RecordDecl>(d);
17750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
17760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1777fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
17785dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 1 /*union*/;
17796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1783bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
17840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
17850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
17860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
17870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
178817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
178917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
17900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
17910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
17920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
17930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1794bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
17950c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
17960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
179790cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
1798bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
179990cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
180090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
18010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
18020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1803bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
18040c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
18050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
18060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
18070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
18080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
18090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
18100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
18110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1812bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
18130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
1814bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
18150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
18160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
18170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1818bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
18190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
18200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
1821bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1822bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1823bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
18246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1825cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
18266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
18276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
18296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1830545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
18313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
18326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18347a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1835797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1836bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
18386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
18396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
1840797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
18416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1843f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
1844f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
18456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
18466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18474ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
18486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1849545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
18503c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
18516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1853bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1854bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
1855bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
1856bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
18576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1858545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
1859cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
18604ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
18614ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
18624ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
18637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
18644ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
18654ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
18664ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
18674ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
18684ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
1869cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
18706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1872bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1873cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
187449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
18754ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
18764ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
18774ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
187849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
187949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
1880396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
18814ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
18824ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
1883396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
1884396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
1885396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
1886cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
1887cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
1888cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1889cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
1890cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
1891cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
1892cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
1893cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
18946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1895fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1896bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive
1897bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
1898fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
1899bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
1900bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
1901bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
19020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1903fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
1904fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
1905fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1906fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
1907fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
19083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1909fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1910fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1911fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1912fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
1913fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
19140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1915fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1916fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1917210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
191801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Str = Attr.getParameterName()->getName();
1919fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1920fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
1921210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
1922210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
1923fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1924fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1925fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
192673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
1927210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
1928fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
192973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
193073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
193173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
193273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
193373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
193473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
193573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
193673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
193773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
193873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
193973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
194073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
194173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
194273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
194373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
194473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1945fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1946fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1947fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1948fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1949210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
19500b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1951210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
19520b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1953fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1954fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
1955210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
19560b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1957fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1958fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1959fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1960fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
1961fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1962fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
1963fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1964fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
1965fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
1966fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1967fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1968fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1969fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
197073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1971183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
197273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
197373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
19742ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
197573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
197673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
197773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
197873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
197973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
198073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
198173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
198273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
198373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1984390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
1985390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
1986390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
1987390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
1988f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
1989f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
1990fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
1991fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
1992fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
19933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1994fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1995fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
19963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1997fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1998fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
199973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
200073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
200173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
200273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2003fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
20040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2005fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
20060b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2007fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
200973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
201073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
201173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
201273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2013fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
20140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2015fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
20160b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2017fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2018fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2019fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
20200b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2021fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
20220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2023fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
20240b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2025fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2026fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2027fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
20280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2029fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2030aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2031aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2032aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2033aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2034fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2035aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2036aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2037aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2038aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2039fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
204073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
204173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
204273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2043f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2044f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2045f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2046f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2047f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2048f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2049f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2050f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2051f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
205273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2053fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2054fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
205573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
205673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2057fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2058fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2059fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2060ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
2061ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2062a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2063ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2064fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2065fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
20660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
20671feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2068d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
2069d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
2070d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2071d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2072d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2073e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
20745bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (!isFunctionOrMethod(d)) {
2075d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
20765dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
2077d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2078d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2079bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2080cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2081d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2082d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
20831feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
20845bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
20855bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
20865bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
20875bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
20885bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2089bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2090c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
20915bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
20925dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
20935bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
20945bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2095bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2096cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
20975bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
20985bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
20997255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
21007255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner                                           Sema &S) {
21017255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
21027255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (Attr.getNumArgs() != 0) {
21037255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
21047255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
21057255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
21067255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
21077255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (!isa<FunctionDecl>(d)) {
21087255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
21097255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    << Attr.getName() << 0 /*function*/;
21107255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
21117255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
21127255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2113f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2114f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
21157255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
21167255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2117ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2118ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2119ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2120ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2121ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2122ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2123ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2124ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2125ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<VarDecl>(d)) {
2126ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2127ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne        << Attr.getName() << 12 /*variable*/;
2128ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2129ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2130ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2131ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2132ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2133ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2134ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2135ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2136ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2137ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2138ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2139ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2140ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2141ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2142ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2143ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2144ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2145ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) {
2146ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2147ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne        << Attr.getName() << 2 /*variable and function*/;
2148ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2149ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2150ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2151ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2152ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2153ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2154ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2155ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2156ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2157ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2158ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2159ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2160ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2161ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2162ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2163ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2164ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2165ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d)) {
2166ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2167ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne        << Attr.getName() << 0 /*function*/;
2168ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2169ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2170ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
21712c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    FunctionDecl *FD = cast<FunctionDecl>(d);
21722c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2173723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
21742c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
21752c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
21762c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
21772c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
21782c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
21792c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
21802c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
21812c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
21822c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
21832c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
21842c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
21852c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2186ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2187ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2188ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2189ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2190ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2191ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2192ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2193ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2194ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2195ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2196ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2197ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2198ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2199ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2200ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d)) {
2201ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2202ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne        << Attr.getName() << 0 /*function*/;
2203ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2204ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2205ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2206ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2207ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2208ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2209ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2210ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2211ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2212ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2213ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2214ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2215ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2216ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2217ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2218ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2219ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2220ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<VarDecl>(d)) {
2221ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2222ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne        << Attr.getName() << 12 /*variable*/;
2223ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2224ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2225ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2226ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2227ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2228ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2229ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2230ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2231ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2232cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
223326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
223426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
223526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
223626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
223726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2238bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2239c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
2240c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
224126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
22425dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
224326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
224426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2245bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22460130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2247cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2248c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2249c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2251cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
225226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
225326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
2254e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnarastatic void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2255e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2256e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2257e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  assert(Attr.isInvalid() == false);
2258e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2259e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  switch (Attr.getKind()) {
2260e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
2261cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2262e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2263e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
2264cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2265e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2266f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
2267cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
226804633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2269e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
2270cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2271e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
227252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
227352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    d->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
227452fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2275e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2276e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2277e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2278e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2279e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2280e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2281ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2282ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  // check the attribute arguments.
2283ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (Attr.getNumArgs() != 1) {
228455d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2285ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2286ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
228755d3aaf9a537888734762170823daf750ea9036dEli Friedman
2288ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (!isFunctionOrMethod(d)) {
2289ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
22905dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
2291ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2292ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
229355d3aaf9a537888734762170823daf750ea9036dEli Friedman
22947a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *NumParamsExpr = Attr.getArg(0);
229555d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2296ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2297ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
229855d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
229955d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
230055d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
230155d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
230255d3aaf9a537888734762170823daf750ea9036dEli Friedman
2303264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov  if (S.Context.Target.getRegParmMax() == 0) {
2304264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
230555d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
230655d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
230755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
230855d3aaf9a537888734762170823daf750ea9036dEli Friedman
2309348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
2310264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2311264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
231255d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
231355d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
231455d3aaf9a537888734762170823daf750ea9036dEli Friedman
2315cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context,
2316cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           NumParams.getZExtValue()));
2317ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2318ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
23197b381985353304a7723acb05911ff91634fa1f27Peter Collingbournestatic void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){
23207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
23217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
23227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
23237b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
23247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "1 or 2";
23257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
23267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
23277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
23287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (!isFunctionOrMethod(d)) {
23297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
23307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      << Attr.getName() << 0 /*function*/;
23317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
23327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
23337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
23347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
23357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
23367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
23377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
23387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
23397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
23417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
23427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
23437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
23447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
23457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
23467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
23477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
23487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
23497b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
23507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
23527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
23537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
23547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
23557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
23567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
23577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
23587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
23597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
23607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
23617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
23627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
23637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
2364bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2365bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // check the attribute arguments.
2366bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Attr.getNumArgs() != 0) {
2367bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2368bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
2369bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2370bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2371bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isa<CXXRecordDecl>(d)
2372bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt   && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) {
2373bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(),
2374bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
2375bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                   : diag::warn_attribute_wrong_decl_type)
2376bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      << Attr.getName() << 7 /*virtual method or class*/;
2377bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
2378bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
23797725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
23807725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
23817725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
23827725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<FinalAttr>()) {
23837725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final";
23847725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
23857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
2386bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2387cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context));
2388bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2389bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
23900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
23917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt// C++0x member checking attributes
23927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===//
23937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
23947725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) {
23957725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
23967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
23977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
23987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
23997725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24007725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<CXXRecordDecl>(d)) {
24017725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
24027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
24037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
24047725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 9 /*class*/;
24057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
24067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
24077725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<BaseCheckAttr>()) {
24097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check";
24107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
24117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
24127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
2413cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context));
24147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
24157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
24177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
24187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
24197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
24207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
24217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<RecordDecl>(d->getDeclContext())) {
24237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    // FIXME: It's not the type that's the problem
24247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
24257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
24267725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
24277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 11 /*member*/;
24287725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
24297725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
24307725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
24327725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<HidingAttr>()) {
24347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding";
24357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
24367725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
24377725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
2438cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context));
24397725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
24407725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24417725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
24427725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
24437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
24447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
24457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
24467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) {
24487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    // FIXME: It's not the type that's the problem
24497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
24507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
24517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
24527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 10 /*virtual method*/;
24537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
24547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
24557725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24567725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
24577725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<OverrideAttr>()) {
24597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override";
24607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
24617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
24627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
2463cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context));
24647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
24657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
24667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===//
2467b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
2468b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
2469b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2470b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
2471b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek                                        Sema &S) {
2472b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
24735dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  QualType RetTy;
2474bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24755dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
24765dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = MD->getResultType();
24775dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
24785dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = FD->getResultType();
24795dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
248021531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    SourceLocation L = Attr.getLoc();
248121531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
248221531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek        << SourceRange(L, L) << Attr.getName() << 3 /* function or method */;
2483b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
2484b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
2485bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24866217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>()
2487183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        || RetTy->getAs<ObjCObjectPointerType>())) {
248821531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    SourceLocation L = Attr.getLoc();
248921531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
249021531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek      << SourceRange(L, L) << Attr.getName();
2491bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
24925dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
2493bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2494b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  switch (Attr.getKind()) {
2495b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
2496b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
2497b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
249831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
2499f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(),
2500f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
250131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
250231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
2503f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(),
2504f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
250531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
2506b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
2507f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher      d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(),
2508f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2509b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2510b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
2511f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher      d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(),
2512f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2513b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2514b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
2515b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
2516b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2517f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2518f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
251911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
252011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
252111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
252211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
252311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
252411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
252511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
252611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
252711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichetstatic void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) {
252811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
252911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
253011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    if (Attr.getNumArgs() != 1) {
253111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
253211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
253311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    }
253411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
253511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2536d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (Str == 0 || Str->isWide()) {
2537d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2538d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
2539d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2540d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2541d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2542d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    llvm::StringRef StrRef = Str->getString();
2543d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2544d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
2545d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
2546d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2547d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
2548d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
2549d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2550d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2551d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2552d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
2553d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2554d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2555d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2556d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2557d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
2558d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
2559d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    llvm::StringRef::iterator I = StrRef.begin();
2560d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly) // Skip the optional '{'
2561d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet       ++I;
2562d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2563d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    for (int i = 0; i < 36; ++i) {
2564d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
2565d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
2566d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2567d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
2568d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
2569d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
2570d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2571d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
2572d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
2573d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
2574d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
257511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
257611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    d->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
257711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
2578d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
257911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
2580f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
2581f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
2582b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
25830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
25840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
25850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
2586a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
2587803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
2588bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
2589bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
2590bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D,
2591bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump                                 const AttributeList &Attr, Sema &S) {
2592e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  if (Attr.isInvalid())
2593e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2594e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2595f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
2596f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis    // FIXME: Try to deal with other __declspec attributes!
2597290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman    return;
2598803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
259963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  case AttributeList::AT_IBAction:            HandleIBAction(D, Attr, S); break;
2600857e918a8a40deb128840308a318bf623d68295fTed Kremenek    case AttributeList::AT_IBOutlet:          HandleIBOutlet(D, Attr, S); break;
2601857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
2602857e918a8a40deb128840308a318bf623d68295fTed Kremenek      HandleIBOutletCollection(D, Attr, S); break;
2603803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
2604ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
26056e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
26064211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
26074211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
2608bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
2609bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
2610803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
26117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_alias:       HandleAliasAttr       (D, Attr, S); break;
26127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_aligned:     HandleAlignedAttr     (D, Attr, S); break;
2613bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
2614af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
2615b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
2616bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
26177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_annotate:    HandleAnnotateAttr    (D, Attr, S); break;
26187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_base_check:  HandleBaseCheckAttr   (D, Attr, S); break;
2619bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
26207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                      HandleDependencyAttr  (D, Attr, S); break;
2621a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  case AttributeList::AT_common:      HandleCommonAttr      (D, Attr, S); break;
2622ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_constant:    HandleConstantAttr    (D, Attr, S); break;
26237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
26247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_deprecated:  HandleDeprecatedAttr  (D, Attr, S); break;
26257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_destructor:  HandleDestructorAttr  (D, Attr, S); break;
2626ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_device:      HandleDeviceAttr      (D, Attr, S); break;
26273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
26289cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    HandleExtVectorTypeAttr(scope, D, Attr, S);
26293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
26307725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_final:       HandleFinalAttr       (D, Attr, S); break;
26317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format:      HandleFormatAttr      (D, Attr, S); break;
26327725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format_arg:  HandleFormatArgAttr   (D, Attr, S); break;
2633ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_global:      HandleGlobalAttr      (D, Attr, S); break;
26347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr   (D, Attr, S); break;
26357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_hiding:      HandleHidingAttr      (D, Attr, S); break;
2636ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_host:        HandleHostAttr        (D, Attr, S); break;
26377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
26387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    HandleLaunchBoundsAttr(D, Attr, S);
26397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
26407725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_mode:        HandleModeAttr        (D, Attr, S); break;
26417725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_malloc:      HandleMallocAttr      (D, Attr, S); break;
264234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  case AttributeList::AT_may_alias:   HandleMayAliasAttr    (D, Attr, S); break;
2643a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  case AttributeList::AT_nocommon:    HandleNoCommonAttr    (D, Attr, S); break;
26447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nonnull:     HandleNonNullAttr     (D, Attr, S); break;
2645dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
2646dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
2647dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
2648dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      HandleOwnershipAttr     (D, Attr, S); break;
2649dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  case AttributeList::AT_naked:       HandleNakedAttr       (D, Attr, S); break;
26507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;
26517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;
26527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_override:    HandleOverrideAttr    (D, Attr, S); break;
2653ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_shared:      HandleSharedAttr      (D, Attr, S); break;
265435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  case AttributeList::AT_vecreturn:   HandleVecReturnAttr   (D, Attr, S); break;
2655b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2656b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
265731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
265831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
2659b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
2660b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
2661b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    HandleNSReturnsRetainedAttr(D, Attr, S); break;
2662b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
26636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
26646f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    HandleReqdWorkGroupSize(D, Attr, S); break;
26656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
2666521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
2667521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      HandleInitPriorityAttr(D, Attr, S); break;
2668521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
26697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_packed:      HandlePackedAttr      (D, Attr, S); break;
26707725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_section:     HandleSectionAttr     (D, Attr, S); break;
26717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
26727725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unused:      HandleUnusedAttr      (D, Attr, S); break;
26737725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_used:        HandleUsedAttr        (D, Attr, S); break;
26747725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_visibility:  HandleVisibilityAttr  (D, Attr, S); break;
2675026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
2676026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
26777725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak:        HandleWeakAttr        (D, Attr, S); break;
267811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  case AttributeList::AT_weakref:     HandleWeakRefAttr     (D, Attr, S); break;
26797725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak_import: HandleWeakImportAttr  (D, Attr, S); break;
2680803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
2681803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
2682803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
26830db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
26840db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
26850db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
2686f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
26877725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nsobject:    HandleObjCNSObject    (D, Attr, S); break;
26887725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_blocks:      HandleBlocksAttr      (D, Attr, S); break;
26897725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_sentinel:    HandleSentinelAttr    (D, Attr, S); break;
26907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_const:       HandleConstAttr       (D, Attr, S); break;
26917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_pure:        HandlePureAttr        (D, Attr, S); break;
26927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_cleanup:     HandleCleanupAttr     (D, Attr, S); break;
26937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nodebug:     HandleNoDebugAttr     (D, Attr, S); break;
26947725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noinline:    HandleNoInlineAttr    (D, Attr, S); break;
26957725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_regparm:     HandleRegparmAttr     (D, Attr, S); break;
2696bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
269705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
269805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
26997255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
27007255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    HandleNoInstrumentFunctionAttr(D, Attr, S);
27017255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
270204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
270304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
270404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
2705f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
270652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2707e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    HandleCallConvAttr(D, Attr, S);
270804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
270911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
271011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    HandleUuidAttr(D, Attr, S);
271111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
2712803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
271382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
271482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
271582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
27167d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
27177d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
2718803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
2719803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2720803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2721803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
2722803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
2723803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
2724f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
2725f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                    const AttributeList *AttrList) {
272611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
272711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    ProcessDeclAttribute(S, D, *l, *this);
272811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
272911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
273011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
273111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
273211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
273311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
273411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
2735dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
273611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
2737803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2738803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2739803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
2740e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
2741e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
27421eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
27437b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
2744e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
2745e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
2746e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
2747e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
2748a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
2749b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
2750b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
2751b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange());
2752b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
2753e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
2754e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
2755e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                           VD->getLocation(), II,
2756a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
275716573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
275816573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
2759b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
2760b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
2761b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange());
2762b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
2763e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2764e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
2765e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
2766e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
2767e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
2768e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
27697b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
2770c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
2771c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
2772c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
2773c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
2774c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
2775cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
2776cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
2777cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
2778c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
2779c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
2780c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
2781c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
2782c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
2783c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
2784c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
2785c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
2786cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
2787e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2788e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
2789e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
27900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
27910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
27920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
27939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
2794d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
2795d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
2796d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  if (!WeakUndeclaredIdentifiers.empty()) {
2797d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall    if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
2798d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall      if (IdentifierInfo *Id = ND->getIdentifier()) {
2799d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
2800d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          = WeakUndeclaredIdentifiers.find(Id);
2801d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
2802d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakInfo W = I->second;
2803d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          DeclApplyPragmaWeak(S, ND, W);
2804d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakUndeclaredIdentifiers[Id] = W;
2805d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
2806e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
2807e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
2808e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2809e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
28100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
28110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
28129cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
2813bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
28140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
28150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
28160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
28170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
28180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
28190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
28209cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      ProcessDeclAttributeList(S, D, Attrs);
2821bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
28220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
28230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
28249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
28250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
282654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
282754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// PushParsingDeclaration - Enter a new "scope" of deprecation
282854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// warnings.
282954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall///
283054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// The state token we use is the start index of this scope
283154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// on the warning stack.
2832f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallSema::ParsingDeclStackState Sema::PushParsingDeclaration() {
283354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclDepth++;
28342f514480c448708ec382a684cf5e035d3a827ec8John McCall  return (ParsingDeclStackState) DelayedDiagnostics.size();
283554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
283654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
2837d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) {
283854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
283954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclDepth--;
284054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
28412f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (DelayedDiagnostics.empty())
284254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
284354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
284454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  unsigned SavedIndex = (unsigned) S;
28452f514480c448708ec382a684cf5e035d3a827ec8John McCall  assert(SavedIndex <= DelayedDiagnostics.size() &&
284654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall         "saved index is out of bounds");
284754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
284858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  unsigned E = DelayedDiagnostics.size();
284958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
28502f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
28512f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
28522f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (D) {
28532f514480c448708ec382a684cf5e035d3a827ec8John McCall    // We really do want to start with 0 here.  We get one push for a
28542f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
28552f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
28562f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
28572f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
28582f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
285958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    for (unsigned I = 0; I != E; ++I) {
28602f514480c448708ec382a684cf5e035d3a827ec8John McCall      if (DelayedDiagnostics[I].Triggered)
28612f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
28622f514480c448708ec382a684cf5e035d3a827ec8John McCall
28632f514480c448708ec382a684cf5e035d3a827ec8John McCall      switch (DelayedDiagnostics[I].Kind) {
28642f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
28652f514480c448708ec382a684cf5e035d3a827ec8John McCall        HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D);
28662f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
28672f514480c448708ec382a684cf5e035d3a827ec8John McCall
28682f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
28692f514480c448708ec382a684cf5e035d3a827ec8John McCall        HandleDelayedAccessCheck(DelayedDiagnostics[I], D);
28702f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
287154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
287254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
287354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
287454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
287558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
287658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  for (unsigned I = SavedIndex; I != E; ++I)
287758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    DelayedDiagnostics[I].destroy();
287858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
28792f514480c448708ec382a684cf5e035d3a827ec8John McCall  DelayedDiagnostics.set_size(SavedIndex);
28802f514480c448708ec382a684cf5e035d3a827ec8John McCall}
28812f514480c448708ec382a684cf5e035d3a827ec8John McCall
28822f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
28832f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
28842f514480c448708ec382a684cf5e035d3a827ec8John McCall    if (D->hasAttr<DeprecatedAttr>())
28852f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
28862f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
28872f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
28882f514480c448708ec382a684cf5e035d3a827ec8John McCall}
28892f514480c448708ec382a684cf5e035d3a827ec8John McCall
28909c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
28912f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
28922f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
28932f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
28942f514480c448708ec382a684cf5e035d3a827ec8John McCall
28952f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
2896ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
2897c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
2898ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
2899ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
2900c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
2901c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
2902ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
290354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
290454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
2905ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramervoid Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
29068e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
29078e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  bool UnkownObjCClass) {
290854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
290954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (ParsingDeclDepth) {
2910c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D,
2911c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                                                    Message));
291254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
291354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
291454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
291554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
291654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
291754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
2918ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
2919c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
2920c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
29218e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
29228e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian    if (!UnkownObjCClass)
29238e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
29248e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian    else
29258e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
29268e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
292754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
2928