SemaDeclAttr.cpp revision 60acea49c1343e5494edb6da20cac6f9d0b6cfb0
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
1306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
131183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
132b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
135506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
136506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
139506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
146085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1476217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
148085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
149085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
150085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1516217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
152085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
153085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
154bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
155085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
156465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
157085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
158085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
159085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
160085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
161085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
162e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
163e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
164e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
165e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
1663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
1673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
1683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
1693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
1719cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor                                    const AttributeList &Attr, Sema &S) {
172545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
173545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
174803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
175545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
1799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
1819cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
1839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
184f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
185f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
186f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
187f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>();
1889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
1899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
1909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    if (Attr.getNumArgs() != 1) {
1919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
1939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    }
1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    sizeExpr = static_cast<Expr *>(Attr.getArg(0));
1956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
1989cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
1999ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
2009cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
201ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
202a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
2059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
2066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
209803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
211545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2123c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
215bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
217cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
222803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
223fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
22408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
2256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
226cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
23296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
23396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
2343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
23596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
23696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
237bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
23963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
24063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
241cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
24263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
24363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
24463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
24563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName();
24663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
24763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
24863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
24963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
25063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (Attr.getNumArgs() > 0) {
25163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
25263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
25363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  }
25463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
25563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
256efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
257efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
258cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
25963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
260efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
26163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
26263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
26396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
26496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
265857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
266857e918a8a40deb128840308a318bf623d68295fTed Kremenek                                     Sema &S) {
267857e918a8a40deb128840308a318bf623d68295fTed Kremenek
268857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
269a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
270857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
271857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
272857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
273857e918a8a40deb128840308a318bf623d68295fTed Kremenek
274857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
275857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
276857e918a8a40deb128840308a318bf623d68295fTed Kremenek  if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) {
277857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
278857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
279857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
2803a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian  if (const ValueDecl *VD = dyn_cast<ValueDecl>(d))
2813a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
2823a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
2833a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
2843a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
2853a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
2863a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
2873a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
2883a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
2893a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
2903a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
2913a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
2923a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
293a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
294a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
295a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
2963a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
297b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
298a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian                        S.getScopeForContext(d->getDeclContext()->getParent()));
299a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
300a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
301a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
302a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
303b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
304a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
305a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
306a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
307a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
308a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
309a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
310a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
311a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
312a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
313cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
314cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
315857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
316857e918a8a40deb128840308a318bf623d68295fTed Kremenek
317eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
318bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
319bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
320d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
321fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3225dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
324eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
325bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
326d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
327eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
330bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
331eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
333bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
334bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
335eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
336f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek    Expr *Ex = static_cast<Expr *>(*I);
337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
338ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
339ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
340fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
341fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
342eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
344bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
345eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
346bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
348fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
34930bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
350eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
352bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
353465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
354eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
355eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
356bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    QualType T = getFunctionOrMethodArgType(d, x);
357dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
358eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
359c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
360fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
3617fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
362eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
363bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
364eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
365eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
366bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
367bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
368bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
3697fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
37046bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
37146bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek      QualType T = getFunctionOrMethodArgType(d, I);
372dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
373d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
37446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
375bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3761db5d140b24bd181644135446fdaca75d8396aa4Ted Kremenek    // No pointer arguments?  The attribute in this case is
3771db5d140b24bd181644135446fdaca75d8396aa4Ted Kremenek    // trivially satisfied.
37860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
37960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
38060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
38160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
38260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
3837fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
38460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
385eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
3867fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3877fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
3887fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
389dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
390cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
391cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
392eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
393eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
394dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekstatic void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
395dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
396dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
397dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
398dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
399dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
400dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
4012a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
4022a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
403dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
404dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
405dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
406dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
407dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
408dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
409dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
410cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
4112a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
4122a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
413cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
414dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
415dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
416dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
417dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4182a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4192a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
420cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
421dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
422dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
423dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
424dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4252a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4262a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
427cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
428dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
429dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
430dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
431dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
432dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4332a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4342a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
4352a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
4362a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
437dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
438dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
439dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!isFunction(d) || !hasFunctionProto(d)) {
440dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName()
441dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << 0 /*function*/;
442dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
443dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
444dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
445dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
446dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
447dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::StringRef Module = AL.getParameterName()->getName();
448dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
449dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
450dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
451dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
452dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
453dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::SmallVector<unsigned, 10> OwnershipArgs;
454dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
4552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
4562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
457dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
458dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Expr *IdxExpr = static_cast<Expr *>(*I);
459dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
460dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
461dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
462dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
463dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
464dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
465dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
466dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
467dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
468dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
469dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
470dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
471dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
472dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
473dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
475dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
476cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
477cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
478dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      QualType T = getFunctionOrMethodArgType(d, x);
480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
482dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
483cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
484dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
485dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
486dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
487dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
488dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
489dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
490cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
491dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
492dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
493dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0));
494dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
495dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
496dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
497dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
498dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
501dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
502dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
503dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
504dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5052a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
5062a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
508dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
509dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
510cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
511cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          i = d->specific_attr_begin<OwnershipAttr>(),
512cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          e = d->specific_attr_end<OwnershipAttr>();
513cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
514cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
515cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
516cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
517cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
518cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
519cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
520dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
521dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
522dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
523dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
524dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
525dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
526dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
527dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
528dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
530cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
531cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
532cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
533cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
534dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
535cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
536cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
537cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
538dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
539dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
54011e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic bool isStaticVarOrStaticFunciton(Decl *D) {
54111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (VarDecl *VD = dyn_cast<VarDecl>(D))
542d931b086984257de68868a64a235c2b4b34003fbJohn McCall    return VD->getStorageClass() == SC_Static;
54311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
544d931b086984257de68868a64a235c2b4b34003fbJohn McCall    return FD->getStorageClass() == SC_Static;
54511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
54611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
54711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
54811e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
54911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
55011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
55111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
55211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
55311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
55411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
55511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
55611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
55711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
55811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
55911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
56011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
56111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
56211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
56311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
56411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
5657a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  const DeclContext *Ctx = d->getDeclContext()->getRedeclContext();
5667a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
5677a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
5687a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl        dyn_cast<NamedDecl>(d)->getNameAsString();
5697a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
57011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
57111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
57211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
57311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
57411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
57511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
57611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
57711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
57811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
57911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
58011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
58111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
58211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
58311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
58411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
58511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
58611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
58711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
58811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
58911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
59011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (!isStaticVarOrStaticFunciton(d)) {
59111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) <<
59211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      dyn_cast<NamedDecl>(d)->getNameAsString();
59311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
59411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
59511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
59611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
59711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
59811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
59911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
60011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
60111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
60211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
60311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
60411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
60511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    if (Str == 0 || Str->isWide()) {
60611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
60711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
60811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
60911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
61011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
61111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
612cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
61311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
61411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
615cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
61611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
61711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
618803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
620545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
6213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
6226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
624bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
625545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
6266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
6276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
628bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
630fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
6313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
6326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
634bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
636bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
637cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
6386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
640bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
641af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
642af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  // check the attribute arguments.
643af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
6443c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
645af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
646af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
6475bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
648c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
6495bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
6505dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
6515bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
6525bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
653bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
654cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
655af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
656af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
65776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
65876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  // check the attribute arguments.
65976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  if (Attr.getNumArgs() != 0) {
66076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
66176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
66276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
6631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6642cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
6651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
6662cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
667cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
6682cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
6692cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
670fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
671fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
6722cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
67376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
67476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
675b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
676b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
677b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  assert(Attr.isInvalid() == false);
678b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context));
679b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
680b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
681b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
682b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek                                       Sema &S) {
683b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
684b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
685b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
686b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
687545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
688e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
689b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek    return;
6906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
691b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
69219c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
69319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    ValueDecl *VD = dyn_cast<ValueDecl>(d);
6943ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
6953ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
696e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
697e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
698b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
699b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      << Attr.getName() << 0 /*function*/;
700b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
70119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
7026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
703b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
704b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
7056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
70735cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
70835cc9627340b15232139b3c43fcde5973e7fad30John Thompsonstatic void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
70935cc9627340b15232139b3c43fcde5973e7fad30John Thompson                                       Sema &S) {
71035cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
71135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
71235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
71335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  According to the PPU ABI specifications, a class with a single member of vector type is returned in
71435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  memory when used as the return value of a function. This results in inefficient code when implementing
71535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  vector classes. To return the value in a single vector register, add the vecreturn attribute to the class
71635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  definition. This attribute is also applicable to struct types.
71735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
71835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
71935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
72035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
72135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
72235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
72335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
72435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
72535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
72635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
72735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
72835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
72935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
73035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
73135cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
73201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<RecordDecl>(d)) {
73335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
73435cc9627340b15232139b3c43fcde5973e7fad30John Thompson      << Attr.getName() << 9 /*class*/;
73535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
73635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
73735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
73835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  if (d->getAttr<VecReturnAttr>()) {
73935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
74035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
74135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
74235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
74301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  RecordDecl *record = cast<RecordDecl>(d);
74401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
74501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
74601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
74701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
74801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
74901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
75001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
75101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
75201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
75301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
75401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
75501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
75601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  for (RecordDecl::field_iterator iter = record->field_begin(); iter != record->field_end(); iter++) {
75701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
75801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
75901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
76001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
76101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
76201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
76301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
764cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
76535cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
76635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
767bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
768bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
769bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
77004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall      << Attr.getName() << 8 /*function, method, or parameter*/;
771bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
772bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
773bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
774bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
775bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
77673798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
77773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
77873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
7793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
78073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
78173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
782bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
783aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall  if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) &&
784aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall      !isa<TypeDecl>(d)) {
785fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
7865dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
78773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
78873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
789bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
790cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
79173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
79273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
793b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
794b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
795b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (Attr.getNumArgs() != 0) {
796b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
797b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
798b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
799bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
800b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
801186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
802b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
803b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
804b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
805b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  } else if (!isFunctionOrMethod(d)) {
806b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8075dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
808b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
809b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
810bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
811cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
812b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
813b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
8143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
8163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
817fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
818fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0 or 1";
8193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
820bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
8213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
8223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
8233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
8243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
8253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
826ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
827ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
828fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
8293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
8303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
8313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
8323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
8333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
834bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
835c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
836fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8375dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
8383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
8393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
8403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
841cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority));
8423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
8433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
8443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
8463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
847fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
848fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner       << "0 or 1";
8493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
850bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
8513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
8523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
8533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
8543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
8553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
856ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
857ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
858fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
8593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
8603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
8613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
8623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
8633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
864bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
8656782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
866fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8675dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
8683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
8693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
8703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
871cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority));
8723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
8733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
874803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
876545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
880bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
881cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context));
8826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
884bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
885bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  // check the attribute arguments.
886bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
887bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
888bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
889bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
890bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
891cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context));
892bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
893bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
894803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
896545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
8973c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
8986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
900bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
901545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
9026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
9036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
904bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
9056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
906fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
9073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
9086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
910bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
911c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  llvm::StringRef TypeStr = Str->getString();
912cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
913bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
914c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
915cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
916c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
917cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
918c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
919cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
920c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
921cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
9226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
92308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
9246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
926bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
927cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
9286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9300db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
9310db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner                                    Sema &S) {
9320db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
9330db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
9340db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
9350db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
936bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
9370db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
9380db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
9390db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
9400db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
9410db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
942bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
943cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
9440db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
9450db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
9460db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
947fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
9482b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
949fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
950fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
9510db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
952fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
953fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
9546217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
955fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
956fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
957fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
958fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
959cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
960fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
961fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
962bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
963f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
964f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
9652b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
966f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
967f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
968f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
969f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
970f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
971f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
972f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
973f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
974cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
975f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
976f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
9779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
978bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
979fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
9803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
9819eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
9829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
983bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
9849eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
9853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
9869eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
9879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
988bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
989cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
99092e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
9919eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
9929eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
993fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
9943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
9959eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
9969eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
997bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
998cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
9999eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
10009eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
1001770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1002770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1003770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1004fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1005fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0, 1 or 2";
1006770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1007bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1008bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1009770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1010770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
1011770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(0));
1012770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1013ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1014ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1015fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1017770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1018770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1019770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1020bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1021770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1022fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1023fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1024770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1025770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1026770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1027770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1028770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1029770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
1030770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(1));
1031770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1032ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1033ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1034fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1036770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1037770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1038770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1039bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1040770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1041770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1042770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1043fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1044fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1045770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1046770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1047770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1048770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1049770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
1050183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1051897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1052bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1053897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1054897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1055897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1056897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1057bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1058897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
10593bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1060770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1061bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
1062770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
1063770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
10643bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1065770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
10662f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
10672f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (isa<BlockDecl>(d)) {
1068bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1069bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
10702f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
10712f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
10722f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1073daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
1074bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
1075183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
10762f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
10773bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
10783bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
10792f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
10802f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1081ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
10822f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1083ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
10842f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
10852f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1086770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1087fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1088ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
1089770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1090770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1091cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos));
1092770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1093770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1094026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
1095026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
1096026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
1097026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1098026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1099026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1100026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1101f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1102026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
11035dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
1104026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1105026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1106bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1107f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1108f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1109f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1110f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1111f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1112f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1113f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1114f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1115f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1116f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1117f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1118f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1119cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1120026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1121026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1122026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
11236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1124545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
11253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
11266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1129f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  /* weak only applies to non-static declarations */
113011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (isStaticVarOrStaticFunciton(D)) {
1131f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) <<
1132f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian      dyn_cast<NamedDecl>(D)->getNameAsString();
1133f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1134f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1135f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
11366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // TODO: could also be applied to methods?
11376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
11386e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
11395dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
11406e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
11416e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1142bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1143cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
11446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
11476e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
11486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
11496e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
11506e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
1151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
11526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
11536e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
11546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
11556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
11566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    isDef = (!VD->hasExternalStorage() || VD->getInit());
11576e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
115806a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis    isDef = FD->hasBody();
1159d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian  } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
1160d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian    // We ignore weak import on properties and methods
11611c90f4dc686ab872013544664c797604a309c563Mike Stump    return;
11625f8f8571c52dbf12fdefb15d2fedbcccb212c15cFariborz Jahanian  } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) {
1163c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian    // Don't issue the warning for darwin as target; yet, ignore the attribute.
11643be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian    if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin ||
1165c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian        !isa<ObjCInterfaceDecl>(D))
1166c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
11673be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian        << Attr.getName() << 2 /*variable and function*/;
11683be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian      return;
11696e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
11706e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
11716e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // Merge should handle any subsequent violations.
11726e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (isDef) {
1173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
11746e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar           diag::warn_attribute_weak_import_invalid_on_definition)
11756e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar      << "weak_import" << 2 /*variable and function*/;
11766e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
11776e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
11786e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1179cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
11806e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
11816e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
11826f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
11836f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                    Sema &S) {
11846f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
11856f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  if (Attr.getNumArgs() != 3) {
11862b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11876f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
11886f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
11896f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
11906f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
11916f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
11926f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    Expr *E = static_cast<Expr *>(Attr.getArg(i));
11936f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1194ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1195ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
11966f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
11976f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
11986f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
11996f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
12006f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
12016f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1202cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1203cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
12046f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
12056f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
12066f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
1207026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
120817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
120917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
121017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
121117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
121217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
121317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
121417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
121517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
1216797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
1217797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
121817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1219797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
122017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
122117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
12221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1223797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1224bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1225a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1226a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1227a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1228797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1229797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
12301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1231a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1232a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1233a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1234a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1235a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1236a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1237cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString()));
123817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
123917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
12406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1241803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
12426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1243545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
12443c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
12456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1247bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1248cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
12496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1251232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1252232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1253232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
12543c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1255232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1256232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1257bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1258cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1259232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1260232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1261232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1262232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1263232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
12643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1265232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1266232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1267bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1268cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1269232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1270232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1271f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1272bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1273f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1274f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1275f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1276bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1277f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1278f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1279f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1280f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1281bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1282f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
1283bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1284f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1285f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1286f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1287f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1288bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1289f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1290c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1291c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: The lookup source location should be in the attribute, not the
1292c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // start of the attribute.
1293f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1294c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor    = S.LookupSingleName(S.TUScope, Attr.getParameterName(), Attr.getLoc(),
1295f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall                         Sema::LookupOrdinaryName);
1296f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
129789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1298f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1299f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1300f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1301bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1302f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1303f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
130489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
1305f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1306f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1307f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1308f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1309f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
131089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
1311f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1312f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1313f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1314bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
131589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
131689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
131789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
131889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1319d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman  if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
1320bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
132189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
132289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
132389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
132489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1325bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1326cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1327f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1328f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1329bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1330bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
13325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Attr.getNumArgs() != 1) {
13335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
13345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
13355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
13365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
13375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
13385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << Attr.getName() << 0 /*function*/;
13395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
13405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1341bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // FIXME: in C++ the implicit 'this' function parameter also counts.  this is
1342bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // needed in order to be compatible with GCC the index must start with 1.
13435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
13445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
13455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
13465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
13475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1348ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1349ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
13505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
13525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
13535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1354bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
13565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
13575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
13585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
13595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1360bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1362bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
13645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1365bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
13675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
13685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
13695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
13706217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
13715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
13725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1373bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
13745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
13755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1376bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
13775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Ty = getFunctionOrMethodResultType(d);
13785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
13795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
13805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
13816217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
13825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
13835b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1384bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
13855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
13865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1387bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1388bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1389cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, Idx.getZExtValue()));
13905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
13915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
13922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
13932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
13942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
13952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
13962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
13973c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
13982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
13992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
14002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
14012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
14022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
14032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
14042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
14052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
14062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
14072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
14082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
14092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
14102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
14112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
14122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
14132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
14142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
14152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
14162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "zcmn_err")
14172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
14182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1419bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1420bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
14213c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
14223c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
14232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
14242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
14252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1426521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
1427521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
1428521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
1429521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian                                   Sema &S) {
1430521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
1431521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1432521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1433521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1434521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1435b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) {
1436b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1437b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1438b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1439b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1440b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  QualType T = dyn_cast<VarDecl>(d)->getType();
1441b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
1442b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
1443b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
1444b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1445b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1446b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1447b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1448b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1449521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
1450521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1451521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1452521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1453521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1454521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  Expr *priorityExpr = static_cast<Expr *>(Attr.getArg(0));
1455b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1456521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
1457521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1458521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1459521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1460521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
1461521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1462521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1463521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
14649f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
1465521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
1466521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1467521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
1468521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1469521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1470521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1471cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum));
1472521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
1473521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1474bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1475bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1476803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
14776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1478545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1479fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
14803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
14816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
14836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1484545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
14853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
14866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
14886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1489620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1490fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
14915dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
14926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
14946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14953568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
14966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
14976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
149801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Format = Attr.getParameterName()->getName();
14996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
15012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
15022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
15032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
15042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
15052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
15063c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
15073c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
15083c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
15093c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
15102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1511fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
151201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
15136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
15156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
1517545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1518803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1519ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1520ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1521fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
15236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
15256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15264fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  // FIXME: We should handle the implicit 'this' parameter in a more generic
15274fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  // way that can be used for other arguments.
15284fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  bool HasImplicitThisParam = false;
15294fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) {
15304fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson    if (MD->isInstance()) {
15314fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson      HasImplicitThisParam = true;
15324fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson      NumArgs++;
15334fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson    }
15344fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  }
15351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1537fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
15383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
15396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
15416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
15436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1544bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15454a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
15464a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
15474a2614e94672c47395abcde60518776fbebec589Sebastian Redl      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
15484a2614e94672c47395abcde60518776fbebec589Sebastian Redl        << "a string type" << IdxExpr->getSourceRange();
15494a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
15504a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
15514a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
15524a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
15531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
15553568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
15566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1558085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1559fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1560fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1561085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1562085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
15632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1564390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1565390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1566803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1567390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1568fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1569fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
15706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1571bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
15726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
15736217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1574390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1575fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1576fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
15776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
15796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
1581545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1582803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1583ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1584ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1585fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
15876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
15896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
15916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
15923568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
15936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
15946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1595803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
15966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
15976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
15986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
15996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
16013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
16022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
16036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1604fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1605fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
16066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
16076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
16086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
16096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1610fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
16113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
16126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1615cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1616cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
16172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
16186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
16196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16200b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
16210b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
16226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1623545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
16243c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
16256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
16290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
1630bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
16310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
16320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
16330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
16340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = dyn_cast<RecordDecl>(d);
16350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
16360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1637fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16385dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 1 /*union*/;
16396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1643bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
16440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
16450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
16460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
16470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
164817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
164917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
16500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
16510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
16520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
16530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1654bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
16550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
16560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
165790cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
1658bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
165990cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
166090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
16610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
16620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1663bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
16640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
16650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
16660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
16670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
16680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
16690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
16700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
16710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1672bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
16730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
1674bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
16750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
16760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
16770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1678bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
16790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
16800c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
1681bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1682bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1683bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
16846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1685cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
16866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
16876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
16896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1690545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
16913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
16926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1694797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
1695797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1696bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
16986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
16996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
1700797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
17016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1703cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString()));
17046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17064ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
17076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1708545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
17093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
17106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1712bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1713bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
1714bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
1715bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
17166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1717545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
1718cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
17194ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
17204ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
17214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
17224ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  S.AddAlignedAttr(Attr.getLoc(), D, static_cast<Expr *>(Attr.getArg(0)));
17234ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
17244ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
17254ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
17264ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
17274ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
1728cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
17296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1731bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1732cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
173349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
17344ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
17354ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
17364ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
173749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
173849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
1739396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
17404ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
17414ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
1742396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
1743396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
1744396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
1745cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
1746cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
1747cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1748cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
1749cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
1750cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
1751cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
1752cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
17536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1754fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1755bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive
1756bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
1757fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
1758bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
1759bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
1760bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
17610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1762fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
1763fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
1764fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1765fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
1766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
17673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1770fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1771fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
1772fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
17730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1775fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1776210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
177701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Str = Attr.getParameterName()->getName();
1778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1779fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
1780210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
1781210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
1782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1783fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1784fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
178573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
1786210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
1787fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
178873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
178973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
179073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
179173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
179273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
179373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
179473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
179573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
179673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
179773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
179873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
179973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
180073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
180173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
180273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
180373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1804fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1805fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1806fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1807fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1808210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
18090b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1810210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
18110b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1812fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1813fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
1814210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
18150b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1816fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1817fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1818fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1819fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
1820fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1821fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
1822fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1823fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
1824fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
1825fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1826fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1827fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1828fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
182973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1830183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
183173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
183273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
18332ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
183473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
183573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
183673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
183773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
183873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
183973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
184073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
184173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
184273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1843390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
1844390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
1845390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
1846390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
1847f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
1848f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
1849fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
1850fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
1851fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
18523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1853fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1854fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
18553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1856fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1857fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
185873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
185973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
186073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
186173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1862fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
18630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
1864fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
18650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
1866fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1867fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
186873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
186973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
187073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
187173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1872fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
18730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
1874fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
18750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
1876fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1877fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
1878fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
18790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
1880fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
18810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
1882fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
18830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
1884fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1885fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
1886fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
18870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
1888fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
1889aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
1890aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
1891aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
1892aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
1893fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
1894aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
1895aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
1896aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
1897aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
1898fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
189973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
190073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
190173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1902f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
1903f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
1904f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1905f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
1906f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
1907f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
1908f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
1909f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
1910f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
191173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1912fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1913fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
191473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
191573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
1916fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1917fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1918fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
1919ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
1920ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
1921a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
1922ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
1923fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
1924fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
19250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
19261feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1927d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
1928d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
1929d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1930d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1931d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1932e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
19335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (!isFunctionOrMethod(d)) {
1934d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
19355dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
1936d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1937d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1938bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1939cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
1940d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
1941d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
19421feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
19435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
19445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
19455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19465bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
19475bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1948bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1949c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
19505bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
19515dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
19525bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
19535bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1954bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1955cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
19565bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
19575bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
19587255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
19597255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner                                           Sema &S) {
19607255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
19617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (Attr.getNumArgs() != 0) {
19627255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19637255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
19647255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
19657255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
19667255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (!isa<FunctionDecl>(d)) {
19677255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
19687255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    << Attr.getName() << 0 /*function*/;
19697255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
19707255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
19717255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
1972cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context));
19737255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
19747255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
1975cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
197626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
197726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
197826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
197926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
198026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
1981bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1982c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
1983c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
198426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
19855dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
198626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
198726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
1988bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19890130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
1990cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
1991c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
1992c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
1993bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1994cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
199526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
199626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
1997e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnarastatic void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1998e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
1999e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2000e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  assert(Attr.isInvalid() == false);
2001e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2002e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  switch (Attr.getKind()) {
2003e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
2004cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2005e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2006e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
2007cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2008e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2009f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
2010cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
201104633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2012e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
2013cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2014e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
201552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
201652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    d->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
201752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2018e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2019e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2020e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2021e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2022e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2023e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2024ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2025ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  // check the attribute arguments.
2026ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (Attr.getNumArgs() != 1) {
202755d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2028ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2029ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
203055d3aaf9a537888734762170823daf750ea9036dEli Friedman
2031ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (!isFunctionOrMethod(d)) {
2032ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
20335dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
2034ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2035ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
203655d3aaf9a537888734762170823daf750ea9036dEli Friedman
203755d3aaf9a537888734762170823daf750ea9036dEli Friedman  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
203855d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2039ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2040ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
204155d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
204255d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
204355d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
204455d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
204555d3aaf9a537888734762170823daf750ea9036dEli Friedman
2046264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov  if (S.Context.Target.getRegParmMax() == 0) {
2047264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
204855d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
204955d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
205055d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
205155d3aaf9a537888734762170823daf750ea9036dEli Friedman
2052348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
2053264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2054264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
205555d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
205655d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
205755d3aaf9a537888734762170823daf750ea9036dEli Friedman
2058cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context,
2059cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           NumParams.getZExtValue()));
2060ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2061ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
2062bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2063bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // check the attribute arguments.
2064bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Attr.getNumArgs() != 0) {
2065bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2066bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
2067bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2068bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2069bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isa<CXXRecordDecl>(d)
2070bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt   && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) {
2071bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(),
2072bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
2073bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                   : diag::warn_attribute_wrong_decl_type)
2074bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      << Attr.getName() << 7 /*virtual method or class*/;
2075bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
2076bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
20777725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
20787725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
20797725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
20807725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<FinalAttr>()) {
20817725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final";
20827725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
20837725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
2084bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2085cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context));
2086bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2087bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
20880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
20897725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt// C++0x member checking attributes
20907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===//
20917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
20927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) {
20937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
20947725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
20957725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
20967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
20977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
20987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<CXXRecordDecl>(d)) {
20997725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
21007725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
21017725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
21027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 9 /*class*/;
21037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
21047725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
21057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<BaseCheckAttr>()) {
21077725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check";
21087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
21097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
21107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
2111cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context));
21127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
21137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
21157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
21167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
21177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
21187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
21197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<RecordDecl>(d->getDeclContext())) {
21217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    // FIXME: It's not the type that's the problem
21227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
21237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
21247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
21257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 11 /*member*/;
21267725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
21277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
21287725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21297725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
21307725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<HidingAttr>()) {
21327725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding";
21337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
21347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
21357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
2136cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context));
21377725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
21387725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21397725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
21407725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (Attr.getNumArgs() != 0) {
21417725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
21427725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
21437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
21447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) {
21467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    // FIXME: It's not the type that's the problem
21477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(),
21487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt           Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
21497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                   : diag::warn_attribute_wrong_decl_type)
21507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      << Attr.getName() << 10 /*virtual method*/;
21517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
21527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
21537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  // FIXME: Conform to C++0x redeclaration rules.
21557725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21567725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  if (d->getAttr<OverrideAttr>()) {
21577725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override";
21587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt    return;
21597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  }
21607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
2161cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context));
21627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt}
21637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt
21647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===//
2165b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
2166b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
2167b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2168b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
2169b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek                                        Sema &S) {
2170b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
21715dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  QualType RetTy;
2172bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21735dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
21745dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = MD->getResultType();
21755dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
21765dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = FD->getResultType();
21775dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
217821531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    SourceLocation L = Attr.getLoc();
217921531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
218021531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek        << SourceRange(L, L) << Attr.getName() << 3 /* function or method */;
2181b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
2182b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
2183bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21846217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>()
2185183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        || RetTy->getAs<ObjCObjectPointerType>())) {
218621531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    SourceLocation L = Attr.getLoc();
218721531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
218821531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek      << SourceRange(L, L) << Attr.getName();
2189bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
21905dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
2191bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2192b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  switch (Attr.getKind()) {
2193b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
2194b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
2195b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
219631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
2197cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
219831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
219931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
2200cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
220131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
2202b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
2203cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context));
2204b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2205b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
2206cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context));
2207b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2208b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
2209b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
2210b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2211f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2212f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
2213f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis         Attr.getKind() == AttributeList::AT_dllexport;
2214f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
2215f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
2216b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
22170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
22180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
22190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
2220a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
2221803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
2222bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
2223bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
2224bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D,
2225bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump                                 const AttributeList &Attr, Sema &S) {
2226e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  if (Attr.isInvalid())
2227e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2228e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2229f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
2230f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis    // FIXME: Try to deal with other __declspec attributes!
2231290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman    return;
2232803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
223363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  case AttributeList::AT_IBAction:            HandleIBAction(D, Attr, S); break;
2234857e918a8a40deb128840308a318bf623d68295fTed Kremenek    case AttributeList::AT_IBOutlet:          HandleIBOutlet(D, Attr, S); break;
2235857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
2236857e918a8a40deb128840308a318bf623d68295fTed Kremenek      HandleIBOutletCollection(D, Attr, S); break;
2237803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
2238ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
22396e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
2240bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
2241bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
2242803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
22437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_alias:       HandleAliasAttr       (D, Attr, S); break;
22447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_aligned:     HandleAlignedAttr     (D, Attr, S); break;
2245bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
2246af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
2247b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
2248bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
22497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_annotate:    HandleAnnotateAttr    (D, Attr, S); break;
22507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_base_check:  HandleBaseCheckAttr   (D, Attr, S); break;
2251bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
22527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                      HandleDependencyAttr  (D, Attr, S); break;
22537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
22547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_deprecated:  HandleDeprecatedAttr  (D, Attr, S); break;
22557725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_destructor:  HandleDestructorAttr  (D, Attr, S); break;
22563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
22579cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    HandleExtVectorTypeAttr(scope, D, Attr, S);
22583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
22597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_final:       HandleFinalAttr       (D, Attr, S); break;
22607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format:      HandleFormatAttr      (D, Attr, S); break;
22617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format_arg:  HandleFormatArgAttr   (D, Attr, S); break;
22627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr   (D, Attr, S); break;
22637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_hiding:      HandleHidingAttr      (D, Attr, S); break;
22647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_mode:        HandleModeAttr        (D, Attr, S); break;
22657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_malloc:      HandleMallocAttr      (D, Attr, S); break;
22667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nonnull:     HandleNonNullAttr     (D, Attr, S); break;
2267dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
2268dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
2269dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
2270dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      HandleOwnershipAttr     (D, Attr, S); break;
22717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;
22727725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;
22737725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_override:    HandleOverrideAttr    (D, Attr, S); break;
227435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  case AttributeList::AT_vecreturn:   HandleVecReturnAttr   (D, Attr, S); break;
2275b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2276b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
227731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
227831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
2279b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
2280b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
2281b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    HandleNSReturnsRetainedAttr(D, Attr, S); break;
2282b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
22836f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
22846f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    HandleReqdWorkGroupSize(D, Attr, S); break;
22856f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
2286521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
2287521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      HandleInitPriorityAttr(D, Attr, S); break;
2288521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
22897725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_packed:      HandlePackedAttr      (D, Attr, S); break;
22907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_section:     HandleSectionAttr     (D, Attr, S); break;
22917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
22927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unused:      HandleUnusedAttr      (D, Attr, S); break;
22937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_used:        HandleUsedAttr        (D, Attr, S); break;
22947725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_visibility:  HandleVisibilityAttr  (D, Attr, S); break;
2295026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
2296026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
22977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak:        HandleWeakAttr        (D, Attr, S); break;
229811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  case AttributeList::AT_weakref:     HandleWeakRefAttr     (D, Attr, S); break;
22997725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak_import: HandleWeakImportAttr  (D, Attr, S); break;
2300803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
2301803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
2302803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
23030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
23040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
23050db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
2306f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
23077725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nsobject:    HandleObjCNSObject    (D, Attr, S); break;
23087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_blocks:      HandleBlocksAttr      (D, Attr, S); break;
23097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_sentinel:    HandleSentinelAttr    (D, Attr, S); break;
23107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_const:       HandleConstAttr       (D, Attr, S); break;
23117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_pure:        HandlePureAttr        (D, Attr, S); break;
23127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_cleanup:     HandleCleanupAttr     (D, Attr, S); break;
23137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nodebug:     HandleNoDebugAttr     (D, Attr, S); break;
23147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noinline:    HandleNoInlineAttr    (D, Attr, S); break;
23157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_regparm:     HandleRegparmAttr     (D, Attr, S); break;
2316bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
231705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
231805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
23197255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
23207255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    HandleNoInstrumentFunctionAttr(D, Attr, S);
23217255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
232204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
232304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
232404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
2325f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
232652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2327e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    HandleCallConvAttr(D, Attr, S);
232804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
2329803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
233082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
233182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
233282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
23337d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
23347d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
2335803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
2336803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2337803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2338803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
2339803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
2340803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
23419cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) {
234211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
234311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    ProcessDeclAttribute(S, D, *l, *this);
234411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
234511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
234611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
234711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
234811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
234911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
235011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
2351dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
235211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
2353803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2354803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2355803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
2356e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
2357e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
23581eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
23597b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
2360e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
2361e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
2362e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
2363e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
2364a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
2365b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
2366b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
2367b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange());
2368b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
2369e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
2370e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
2371e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                           VD->getLocation(), II,
2372a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
237316573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
237416573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
2375b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
2376b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
2377b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange());
2378b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
2379e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2380e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
2381e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
2382e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
2383e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
2384e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
23857b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
2386c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
2387c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
2388c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
2389c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
2390c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
2391cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
2392cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
2393cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
2394c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
2395c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
2396c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
2397c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
2398c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
2399c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
2400c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
2401c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
2402cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
2403e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2404e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
2405e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
24060744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
24070744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
24080744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
24099cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
2410e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  // Handle #pragma weak
2411e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
2412e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    if (ND->hasLinkage()) {
2413e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier());
2414e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      if (W != WeakInfo()) {
24157b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn        // Identifier referenced by #pragma weak before it was declared
24167b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn        DeclApplyPragmaWeak(S, ND, W);
2417e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn        WeakUndeclaredIdentifiers[ND->getIdentifier()] = W;
2418e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
2419e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
2420e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2421e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
24220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
24230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
24249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
2425bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24260744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
24270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
24280744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
24290744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
24300744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
24310744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
24329cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      ProcessDeclAttributeList(S, D, Attrs);
2433bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
24350744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
24369cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
24370744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
243854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
243954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// PushParsingDeclaration - Enter a new "scope" of deprecation
244054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// warnings.
244154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall///
244254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// The state token we use is the start index of this scope
244354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// on the warning stack.
2444f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallSema::ParsingDeclStackState Sema::PushParsingDeclaration() {
244554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclDepth++;
24462f514480c448708ec382a684cf5e035d3a827ec8John McCall  return (ParsingDeclStackState) DelayedDiagnostics.size();
244754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
244854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
2449d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) {
245054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
245154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclDepth--;
245254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
24532f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (DelayedDiagnostics.empty())
245454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
245554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
245654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  unsigned SavedIndex = (unsigned) S;
24572f514480c448708ec382a684cf5e035d3a827ec8John McCall  assert(SavedIndex <= DelayedDiagnostics.size() &&
245854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall         "saved index is out of bounds");
245954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
246058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  unsigned E = DelayedDiagnostics.size();
246158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
24622f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
24632f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
24642f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (D) {
24652f514480c448708ec382a684cf5e035d3a827ec8John McCall    // We really do want to start with 0 here.  We get one push for a
24662f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
24672f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
24682f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
24692f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
24702f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
247158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    for (unsigned I = 0; I != E; ++I) {
24722f514480c448708ec382a684cf5e035d3a827ec8John McCall      if (DelayedDiagnostics[I].Triggered)
24732f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
24742f514480c448708ec382a684cf5e035d3a827ec8John McCall
24752f514480c448708ec382a684cf5e035d3a827ec8John McCall      switch (DelayedDiagnostics[I].Kind) {
24762f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
24772f514480c448708ec382a684cf5e035d3a827ec8John McCall        HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D);
24782f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
24792f514480c448708ec382a684cf5e035d3a827ec8John McCall
24802f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
24812f514480c448708ec382a684cf5e035d3a827ec8John McCall        HandleDelayedAccessCheck(DelayedDiagnostics[I], D);
24822f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
248354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
248454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
248554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
248654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
248758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
248858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  for (unsigned I = SavedIndex; I != E; ++I)
248958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    DelayedDiagnostics[I].destroy();
249058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
24912f514480c448708ec382a684cf5e035d3a827ec8John McCall  DelayedDiagnostics.set_size(SavedIndex);
24922f514480c448708ec382a684cf5e035d3a827ec8John McCall}
24932f514480c448708ec382a684cf5e035d3a827ec8John McCall
24942f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
24952f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
24962f514480c448708ec382a684cf5e035d3a827ec8John McCall    if (D->hasAttr<DeprecatedAttr>())
24972f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
24982f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
24992f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
25002f514480c448708ec382a684cf5e035d3a827ec8John McCall}
25012f514480c448708ec382a684cf5e035d3a827ec8John McCall
25029c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
25032f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
25042f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
25052f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
25062f514480c448708ec382a684cf5e035d3a827ec8John McCall
25072f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
25082f514480c448708ec382a684cf5e035d3a827ec8John McCall  Diag(DD.Loc, diag::warn_deprecated)
25092f514480c448708ec382a684cf5e035d3a827ec8John McCall    << DD.DeprecationData.Decl->getDeclName();
251054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
251154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
251254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallvoid Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) {
251354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
251454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (ParsingDeclDepth) {
25152f514480c448708ec382a684cf5e035d3a827ec8John McCall    DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D));
251654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
251754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
251854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
251954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
252054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
252154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
252254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
252354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  Diag(Loc, diag::warn_deprecated) << D->getDeclName();
252454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
2525