SemaDeclAttr.cpp revision db33e14661c7a118a2d9a777ae69c0ecaa036e1e
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"
20f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h"
21fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2219510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
239c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
24797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
269c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of
29883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
30db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskienum AttributeDeclType {
31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunction,
32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedUnion,
33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableOrFunction,
34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionOrMethod,
35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameter,
36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameterOrMethod,
37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrBlock,
38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassOrVirtualMethod,
39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrParameter,
40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClass,
41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVirtualMethod,
42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassMember,
43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariable,
44883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedMethod,
45db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  ExpectedVariableFunctionOrLabel,
46db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  ExpectedFieldOrGlobalVar
47883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall};
48883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall
49e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
52e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
5387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D,
54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
5687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
6087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
64bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
666217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
67755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
686217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
69d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
70183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
76d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
77a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
7887c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) {
7987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return getFunctionType(D, false) != NULL;
80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
82a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
84d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
8587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) {
8687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isFunction(D)|| isa<ObjCMethodDecl>(D);
87d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
9287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
9387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isFunctionOrMethod(D))
94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
9687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
10087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<BlockDecl>(D);
101620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
102620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
104711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
10587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) {
106f85e193739c953358c865005855253af4f68a497John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
10787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
10887c44604325578b8de07d768391c1c9432404f5aChandler Carruth         isa<ObjCPropertyDecl>(D);
109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
110711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
111d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
112d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
113620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
11487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) {
11587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
11672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
117620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
11887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
119d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
1213568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
123d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
125d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
12687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) {
12787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
12872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
12987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
130d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
13187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_size();
1323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1333568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
13587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
13672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
13787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
138d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
139bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
1413568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1423568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
14387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) {
14487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
1455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
14687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->getResultType();
1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
14987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) {
15087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D)) {
15172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
15387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
154db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
155d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
15687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    return cast<ObjCMethodDecl>(D)->isVariadic();
1573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
16087c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) {
16187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
16207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
16507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
167183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
168b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
171506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
172506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
175506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
182085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1836217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
184085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1876217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
189085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
191085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
192465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
197085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
1991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth                                  unsigned int Num) {
2001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (Attr.getNumArgs() != Num) {
2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    return false;
2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  }
2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  return true;
2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth}
2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
208fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
209db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski/// \brief Check the total number of argumenation, whether parsed by clang
210db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski/// as arguments or parameters. Outputs a warning.
211db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski/// \return false if the number of argumenation units does not match expectation
212db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski///
213db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic bool checkAttributeNumArgsPlusParams(Sema &S, const AttributeList &Attr,
214db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                             unsigned int Num,
215db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                             bool moreok = false) {
216db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  unsigned int numArgsPlusParams = 0;
217db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (Attr.getParameterName())
219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    numArgsPlusParams++;
220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  numArgsPlusParams += Attr.getNumArgs();
222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
223db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (moreok && numArgsPlusParams < Num) {
224db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
225db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return false;
226db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
227db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
228db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!moreok && numArgsPlusParams != Num) {
229db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
230db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return false;
231db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
232db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
233db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  return true;
234db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
235db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
236db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski///
237fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var
238fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable
239fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
240fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic bool mayBeSharedVariable(Decl *D) {
241fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (isa<FieldDecl>(D))
242fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return true;
243fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if(VarDecl *vd = dyn_cast<VarDecl>(D))
244fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
245fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
246fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
247fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
248fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
249fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
250fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type.
251fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message.
252fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise
253fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
254fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskibool checkIsPointer(Sema & S, Decl * D, const AttributeList & Attr) {
255fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if(ValueDecl * vd = dyn_cast <ValueDecl>(D)) {
256fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
257db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    if(QT->isAnyPointerType()) {
258fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    }
260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_pointer_attribute_wrong_type)
261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
262fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
263fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
264fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
265fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
266fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
267fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
268fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
269e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
270e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
271e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
272e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
2733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
2743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
2753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
2763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
277fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
278fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
279fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
280fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
281fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
282fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
283fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
284fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
285fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
286fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
287fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << 15; /*fields and global vars*/;
288fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
289fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
290fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
291fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
292fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
293fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
294fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
295fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getLoc(), S.Context));
296fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
297fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getLoc(), S.Context));
298fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
299fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
300db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
301db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                 bool pointer = false) {
302db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
303db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
304db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!checkAttributeNumArgsPlusParams(S, Attr, 1))
305db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
306db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
307db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
308db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
309db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
310db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << 15; /*fields and global vars*/;
311db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
312db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
313db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
314db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
315db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
316db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
317db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
318db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getLoc(), S.Context));
319db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
320db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getLoc(), S.Context));
321db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
322db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
323db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
324fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
325fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
326fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
327fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
328fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
329fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
330fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
331fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
332fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
333fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
334fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
335fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
336fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
337fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
338fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getLoc(), S.Context));
339fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
340fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) LockableAttr(Attr.getLoc(), S.Context));
341fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
342fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
343fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
344fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
345fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
346fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
347fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
348fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
349fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
350fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isFunction(D)) {
351fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
352fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
353fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
354fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
355fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
356fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getLoc(),
357fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
358fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
359fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
360db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
361db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
362db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
363db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
364db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!checkAttributeNumArgsPlusParams(S, Attr, 1, /*moreok=*/true))
365db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
366db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
367db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
368db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
369db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
370db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << 15; /*fields and global vars*/;
371db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
372db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
373db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
374db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
375db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getLoc(), S.Context));
376db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
377db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getLoc(), S.Context));
378db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
379db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
380db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
381db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool exclusive = false) {
382db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
383db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
384db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
385db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!isFunction(D)) {
387db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
388db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
389db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
392db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
393db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getLoc(),
394db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                                           S.Context));
395db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
396db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getLoc(),
397db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                                        S.Context));
398db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
399db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
400db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
401db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                      bool exclusive = false) {
402db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
403db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
404db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!checkAttributeNumArgsPlusParams(S, Attr, 1, /*moreok=*/true))
405db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
406db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
407db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!isFunction(D)) {
408db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
409db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
410db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
411db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
412db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
413db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
414db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getLoc(),
415db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                                           S.Context));
416db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
417db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getLoc(),
418db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                                        S.Context));
419db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
420db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
421db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
422db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
423db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool exclusive = false) {
424db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
425db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
426db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!checkAttributeNumArgsPlusParams(S, Attr, 1, /*moreok=*/true))
427db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
428db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
429db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!isFunction(D)) {
430db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
431db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
432db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
433db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
434db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
435db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
436db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getLoc(),
437db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                                           S.Context));
438db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
439db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getLoc(),
440db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                                        S.Context));
441db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
442db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
443db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
444db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
445db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                     const AttributeList &Attr) {
446db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
447db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
448db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
449db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
450db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!isFunction(D)) {
451db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
452db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
453db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
455db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
456db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getLoc(), S.Context));
457db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
458db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
459db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
460db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                     const AttributeList &Attr) {
461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
462db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
463db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!checkAttributeNumArgsPlusParams(S, Attr, 1))
464db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
465db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
466db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!isFunction(D)) {
467db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
468db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
469db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
470db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
471db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
472db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getLoc(), S.Context));
473db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
474db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
475db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
476db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                     const AttributeList &Attr) {
477db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
478db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
479db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!checkAttributeNumArgsPlusParams(S, Attr, 1, /*moreok=*/true))
480db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
482db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!isFunction(D)) {
483db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
485db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
486db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
487db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
488db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getLoc(), S.Context));
489db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
491db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
4921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
4931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
49487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
495545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
496803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
497545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
4986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
499bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
5019cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
5029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
5039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
5049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
5059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
506f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
507f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
508f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
5094ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
5104ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
5114ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
5124ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
5134ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
5144ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
5159cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
5169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
5171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
5189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
5191731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
5207a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5229cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
5239cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
5249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
5259ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
5269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
527ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
528a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
529bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
5309cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
5319cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
5366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
5371731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
5386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
539bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
54087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
541cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
54287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
5436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
5446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
5456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
546803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
547fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
54808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
550cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
5516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
5523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
5536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
55687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
557c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getLoc(), S.Context));
558c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
559c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
560c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
561c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
5621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
56396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
5641731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
56596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
566bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
56763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
56887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
56963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
57087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
57163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
57263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
57363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
5744ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
57563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
57663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
5771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
57863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
5791731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
58063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
58163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
58263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
583efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
58487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D)) {
58587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
58663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
587efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
58863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
5894ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
59096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
59196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
5921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
5931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
594857e918a8a40deb128840308a318bf623d68295fTed Kremenek
595857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
596a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
597857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
598857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
599857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
600857e918a8a40deb128840308a318bf623d68295fTed Kremenek
601857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
602857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
60387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!(isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
6044ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
605857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
606857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
60787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
6083a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
6093a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
6103a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
6113a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
6123a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
61387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6143a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
6153a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
6163a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
6173a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
6183a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
6193a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
620a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
621a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
622a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
6233a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
624b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
62587c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
626a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
627a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
628a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
629a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
630b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
631a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
632a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
633a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
634a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
635a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
636a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
637a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
638a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
639a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
64087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
641cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
642857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
643857e918a8a40deb128840308a318bf623d68295fTed Kremenek
644d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
64568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
64668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
64768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
64868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
64968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
65068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
65168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
65268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
65368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
65468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
65568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
65668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
65768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
65868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
6591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
660bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
661bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
66287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
663fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
664883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
665eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
666eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
667bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
66807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
66907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
67087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
67187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
672eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
673eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
6745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
675bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
676eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
677eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
678bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
679bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
680eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
6817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
682eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
683ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
684ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
685fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
686fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
687eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
688eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
689bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
690eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
691bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
692eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
693fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
69430bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
695eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
696eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
697bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
698465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
69907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
70007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
70107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
70207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
70307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
70407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
70507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
70607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
70707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
708eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
709eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
71087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
711d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
71268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
713dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
714eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
715c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
716fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
7177fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
718eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
719bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
720eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
721eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
722bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
723bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
724bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
7257fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
72687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
72787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
728d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
729dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
730d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
73146bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
733ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
73460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
73560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
73660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
73760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
73860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
7397fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
74060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
741eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
7427fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
7437fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
7447fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
745dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
74687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
747cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
748eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
749eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
7501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
751dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
752dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
753dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
754dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
755dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
756dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
7572a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
7582a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
759dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
760dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
761dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
762dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
763dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
764dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
765dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
766cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
7672a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
7682a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
769cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
770dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
771dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
772dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
773dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
7742a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
7752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
776cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
777dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
778dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
779dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
780dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
7812a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
7822a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
783cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
784dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
785dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
786dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
787dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
788dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
7892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
7902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
7912a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
7922a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
793dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
794dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
79587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
796883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
797883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
798dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
799dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
800dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
80107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
80207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
80387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
80487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
805dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
8065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
807dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
808dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
809dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
810dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
811dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
8125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
813dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
8142a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
8152a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
816dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
8177a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
818dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
819dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
820dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
821dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
822dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
823dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
824dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
825dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
826dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
827dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
828dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
829dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
830dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
831dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
832dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
833dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
83407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
83507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
83607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
83707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
83807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
83907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
84007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
84107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
84207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
843dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
844cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
845cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
846dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
84787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
848dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
849dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
850dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
851cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
852dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
853dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
854dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
855dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
856dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
857dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
858cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
859dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
860dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
8617a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
862dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
863dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
864dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
865dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
866dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
867dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
868dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
869dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
870dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
871dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
872dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
8732a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
8742a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
875dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
876dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
877dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
878cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
87987c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
88087c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
881cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
882cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
883cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
884cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
885cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
886cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
887cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
888dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
889dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
890dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
891dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
892dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
893dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
894dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
895dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
896dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
897dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
898cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
899cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
900cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
901cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
902dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
903cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
90487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
905cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
906dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
907dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
908332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
909332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
910332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
911332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
912332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
913332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
914332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
915332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
916332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
917332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
918332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
919332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
920332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
921332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
922332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
923332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
924332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
92511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
92611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
92711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
9281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
92911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
93011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
93111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
93211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
93311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
93411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
93587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
936332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
937883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
938332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
939332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
940332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
94187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
942332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
94311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
94411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
94511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
94611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
94711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
94811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
94911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
95011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
95111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
95211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
95387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
9547a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
9557a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
956332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
9577a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
95811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
95911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
96011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
96111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
96211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
96311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
96411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
96511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
96611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
96711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
96811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
96911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
97011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
97111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
97211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
97311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
97411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
97511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
97611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
97711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
978332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
979332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
98011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
98111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
98211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
98311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
98411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
98511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
98611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
98711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
9887a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
98911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
99011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
99111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
9925cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
99311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
99411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
99511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
99611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
99711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
99811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
99987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
1000f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
100111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
100211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
100387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
100411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
100511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
10061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
10076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1008545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
10093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
10106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1012bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10137a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
10146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
10156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1016bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10175cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1018fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
10193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
10206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1022bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1023db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar  if (S.Context.Target.getTriple().isOSDarwin()) {
1024f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1025f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1026f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1027f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
10286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1029bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
103087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
1031f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
10326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1035dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
10361731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1037dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1038dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
103987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1040dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1041883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1042dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1043dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1044dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
104587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
1046dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1047dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
10481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
10491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1050dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1051831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
10523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1053af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1054af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
10555bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
105687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
10575bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1058883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
10595bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
10605bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1061bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
106287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
1063af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1064af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
10651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1066dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1067831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
106876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
106976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
107076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
10711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
107287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
10731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
10742cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
107587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
10762cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
10772cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1078fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1079fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
10802cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
108176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
108276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
10831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
108434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
10851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
108634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
108734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
108887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
108934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
109034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
10911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
109256aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
109387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
109487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
1095722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1096722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1097883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1098a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1099a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
11001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
110156aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
110287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
110387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
1104722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1105722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1106883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1107a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1108a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
11091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
111087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1112711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1113711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
111487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1115711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1116883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1117711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1118711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1119711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
112087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
1121711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1122711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1123711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1124831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1125711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1126711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1127711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1128711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1129711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1130711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1131b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1132b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
11331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
11341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1135b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1136b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1137b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1138b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
11391731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
11401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1141b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
114287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
114387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
11443ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
11453ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1146e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1147e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1148b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1149883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1150b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
115119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
11526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1153b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
115487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
11556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
115735cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
11581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
115935cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
116035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
116135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1162f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1163f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1164f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1165f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1166f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
116735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
116835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
116935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
117035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
117135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
117235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
117335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
117435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
117535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
117635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
117735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
117835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
117935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
118035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
118135cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
118287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
118335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1184883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
118535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
118635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
118735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
118887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
118935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
119035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
119135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
119235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
119387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
119401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
119501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
119601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
119701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
119801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
119901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
120001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
120101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
120201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
120301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
120401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
120501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1206f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1207f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
120801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
120901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
121001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
121101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
121201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
121301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
121401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
121587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
121635cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
121735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
12181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
121987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1220bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1221883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1222bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1223bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1224bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1225bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1226bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
12271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
122873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1229831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
12303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
123173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
123273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1233bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
123487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
123587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1236fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1237883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
123873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
123973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1240bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
124187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
124273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
124373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
12441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1245b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1246831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1247b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1248b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1249b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
125187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1252186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1253b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1254b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1255b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
125687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1257b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1258883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1259b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1260b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1261bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
126287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
1263b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1264b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
12651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
12663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1267bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1268bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
12693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1270bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
12713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
12723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
12733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
12747a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
12753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1276ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1277ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1278fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
12793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
12803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
12813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
12823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
12833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1284bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
128587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1286fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1287883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
12883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
12893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
12903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
129187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
1292f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
12933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
12943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
12951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
12963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1297bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1298bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
12993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1300bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
13013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
13023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
13033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
13047a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
13053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1306ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1307ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1308fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
13103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
13113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
13123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
13133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1314bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
131587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1316fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1317883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
13183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
13193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
13203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
132187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1322f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
13233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
13243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
13251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1326951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1327951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1328bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1329c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1330c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1331951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1332c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
13335f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1334951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1335951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1336c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1337951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1338951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1339c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1340c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1341951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
13426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1343bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
134487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
13456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1348951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1349951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1350bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1351bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1352bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1353951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1354c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
13555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1356951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1357951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1358c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1359951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1360c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1361c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1362c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1363951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1364c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
136587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
1366bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1367bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1368742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1369742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1370742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1371742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1372742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1373742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1374742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1375742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1376742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1377742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                          Attr.getLoc(), S.Context));
1378742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1379742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
13801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
13811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
13820a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
13830a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
13840a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
13855f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
13860a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
13870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
13880a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
13890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
13900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
13910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
13920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
13930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
13940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
13950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
13960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1397b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
13980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
13990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // Ensure that Introduced < Deprecated < Obsoleted (although not all
14000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
14010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
14020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Deprecated.Version)) {
14030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
14040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
14050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
14060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
14070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
14080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
14090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
14100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Obsoleted.Version)) {
14110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
14120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
14130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
14140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
14150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
14160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
14170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
14180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Deprecated.Version < Obsoleted.Version)) {
14190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
14200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
14210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
14220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
14230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
14240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
142587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
14260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
14270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
14280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1429b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1430b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                IsUnavailable));
14310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
14320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
14331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
14351731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
14366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1437bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14387a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
14396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
14406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1441bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14425cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1443fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
14443c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
14456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1447bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1449cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1450bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1451c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1452cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1453c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1454cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1455c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1456cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1457c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1458cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
14596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
146008631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
14616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1463bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
146487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
14656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
14681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1469d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1470d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
147187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1472883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1473d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1474d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1475d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
147687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
147787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
147887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1479d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1480d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
148187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1482d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
148387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1484d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1485d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1486d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
14875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1488d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1489d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1490d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1491d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1492d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1493d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1494d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1495d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1496d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1497d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1498d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1499d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1500d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1501d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1502d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1503d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
150487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1505d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1506d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1507d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1508f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1509f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1510f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1511f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1512f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1513f85e193739c953358c865005855253af4f68a497John McCall    return;
1514f85e193739c953358c865005855253af4f68a497John McCall  }
1515f85e193739c953358c865005855253af4f68a497John McCall
151687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getLoc(),
1517f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1518d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1519d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
15201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
15211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
15221731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
15230db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1524bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
15260db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
15270db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
15280db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
15290db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1530bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1531cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
15320db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
15330db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
15341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1535fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
15362b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1537fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1538fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1539162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1540fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1541fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
15426217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1543fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1544fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1545fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1546fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1547cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1548fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1549fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1550bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
15511b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1552f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
15532b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1554f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1555f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1556f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1557f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1558f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1559f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1560f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1561f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1562cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1563f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1564f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
15651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1566bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1567fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
15683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
15699eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
15709eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1571bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
15733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
15749eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
15759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1576bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1577cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
157892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
15799eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
15809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1581fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
15823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
15839eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
15849eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1585bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
158687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
15879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
15889eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
15891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1590770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1591770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1592bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1593770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1594bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1595bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1596770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1597770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
15987a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1599770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1600ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1601ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1602fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
16033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1604770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1605770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1606770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1607bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1608770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1609fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1610fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1611770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1612770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1613770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1614770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1615770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1616770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
16177a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1618770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1619ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1620ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1621fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
16223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1623770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1624770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1625770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1626bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1627770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1628770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1629770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1630fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1631fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1632770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1633770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1634770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1635770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
163687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1637183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1638897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1639bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1640897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1641897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1642897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1643897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1644bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1645897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
16463bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1647770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1648bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
164987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1650770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
16513bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1652770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
16532f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
165487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (isa<BlockDecl>(D)) {
1655bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1656bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
16572f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
165887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
16592f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1660daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
166187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1662f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
16632f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
16643bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
16653bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
16662f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
16672f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1668ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
16692f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1670883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
16712f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
16722f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1673770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1674fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1675883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1676770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1677770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
167887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1679f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1680770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1681770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
16821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1683026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
16841731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1685026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1686026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1687f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1688026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1689883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1690026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1691026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1692bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1693f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1694f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1695f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1696f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1697f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1698f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1699f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1700f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1701f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1702f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1703f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1704f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1705cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1706026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1707026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
17081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
17096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
171087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
171187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
17126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
171587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
171687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
171787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1718f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1719f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1720f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
172187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1722332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1723332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1724332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
172587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
17266e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
17276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1728bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
172987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  nd->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
17306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
17336e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
17341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
17356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
17361731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
17376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
17386e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
17396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
17400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
17410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
17420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
17430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
17440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
1745def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1746db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar             (S.Context.Target.getTriple().isOSDarwin() &&
1747def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor              isa<ObjCInterfaceDecl>(D))) {
1748def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
1749def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
1750c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1751883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
17526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
17536e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
17546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
17556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1756cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
17576e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
17586e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
17591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
17601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
17616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
17621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
17636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
17646f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
17656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
17666f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
17677a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
17686f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1769ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1770ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
17716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
17726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
17736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
17746f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
17756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
17766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1777cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1778cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
17796f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
17806f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
17816f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
17821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
178317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
17841731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
178517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
178617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
178717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
178817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
17897a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1790797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
179117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1792797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
179317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
179417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
17951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1796797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1797bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1798a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1799a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1800a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1801797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1802797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
18031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1804a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1805a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1806a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1807a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1808a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1809a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1810f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1811f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
181217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
181317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
18146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1817831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
18183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
18196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1821b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
182287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
1823b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
1824b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      Existing->setLocation(Attr.getLoc());
1825b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
182687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
1827b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
18286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
18296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1831232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1832831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
18333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1834232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1835232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1836bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
183787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
1838b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
1839b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor     Existing->setLocation(Attr.getLoc());
1840b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
184187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1842b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
1843232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1844232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
18451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1846232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
18471731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1848232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1849bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
185087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1851232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1852232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
18531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1854bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1855f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1856f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1857f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1858bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1859f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1860f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1861f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1862f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
186487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
1865bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1866f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1867f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1868f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1869f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1870bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1871f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1872c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1873f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1874f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1875f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1876f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
1877f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1878f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1879f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1880f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1881bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1882f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1883f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
1884f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1885f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
1886f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1887f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1888f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1889f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1890f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
1891f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1892f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
1893f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1894f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1895f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1896bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
189789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
189889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
189989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
190089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1901b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
1902b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
1903f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
190489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
190589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
190689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
190789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1908bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
190987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1910223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1911f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1912f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1913bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1914bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
19151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
19175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
19181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
191987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
19205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1921883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
19225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
19235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
192407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
192507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
192607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
192787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
192887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
19295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
193007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
19315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
19327a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
19335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1934ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1935ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
19365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
19375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
19385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
19395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1940bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
19425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
19435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
19445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
19455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1946bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1948bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
194907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
195007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
195107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
195207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
195307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
195407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
195507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
195607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
195707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
19585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
195987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
1960bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
19625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
19635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
19645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
19656217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
19665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
19675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1968bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
19695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
19705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1971bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
197287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
19735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
19745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
19755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
19766217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
19775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
19785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1979bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
19805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
19815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1982bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1983bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
198487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
198507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
19865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
19875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
19882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
19892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
19902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
19912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
19922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
19933c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
19942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
19952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
19962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
19972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
19982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
19995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
20002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
20012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
20022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
20032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
20042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
20052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
20062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
20072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
20082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
20092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
20102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
20112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
2012cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2013cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
20142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
20152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2016bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2017bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
20183c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
20193c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
20202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
20212b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
20222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2023521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2024521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
20251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
20261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
2027521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
2028521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2029521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2030521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2031521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
203287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2033b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2034b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2035b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2036b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
203787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2038b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2039b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2040b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2041b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2042b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2043b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2044b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2045b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2046521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2047521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2048521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2049521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2050521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
20517a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2052b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2053521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2054521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2055521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2056521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2057521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2058521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2059521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2060521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
20619f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2062521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2063521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2064521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2065521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2066521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2067521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
206887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
2069f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2070521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2071521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2072bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2073bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
20741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2076545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2077fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
20783c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
20796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
20816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2082545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
20833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
20846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
20866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
208787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2088fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2089883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
20906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
20926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
209307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
209407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
209587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
209687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
20976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
20986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
21006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
21022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
21032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
21042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
21052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
21062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
21073c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
21083c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
21093c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
21103c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
21112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2112fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
211301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
21146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
21166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
21187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2119803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2120ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2121ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2122fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
21233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
21246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
21266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2128fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
21293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
21306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
21326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
21346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2135bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21364a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
21374a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
213807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
213907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
214007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
21414a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
21424a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
21434a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
21444a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
21451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
214787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
21486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21492b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2150085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2151fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2152fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2153085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2154085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
21552b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2156390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2157390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2158803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2159390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2160fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2161fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
21626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2163bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
21646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
21656217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2166390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2167fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2168fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
21696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
21716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
21737a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2174803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2175ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2176ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2177fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
21783c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
21796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
21816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
21836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
218487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
21856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
21866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
218787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
21886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
21896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
21906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
21916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
21933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
21942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
21956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2196fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2197fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
21986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
21996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
22006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
22016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2202fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
22033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
22046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2207b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2208b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
220987c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
221087c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2211b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2212b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2213b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2214b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2215b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2216b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2217b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2218b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2219b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->setLocation(Attr.getLoc());
2220b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2221b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2222b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2223b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
222487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
2225cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
22262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
22276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
22286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
22301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
22316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
22321731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
22336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
22356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
22370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
223887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
22390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
22400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
22410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
224287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
22430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
22440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2245fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2246883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
22476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
2251bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
22520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
22530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
22540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
22550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
225617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
225717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
22580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
22590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
22600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
22610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2262bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
22630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
22640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
226590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2266bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
226790cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
226890cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
22690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
22700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2271bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
22720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
22730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
22740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
22750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
22760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
22770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
22780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
22790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2280bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
22810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2282bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
22830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
22840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
22850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2286bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
22870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
22880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2289bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2290bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2291bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
22926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2293cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
22946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
22956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
22976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
22981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
22996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
23017a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2302797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2303bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
23056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
23066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2307797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
23086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
231087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
2311f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
23126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
23136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
23156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2316545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
23173c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
23186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2320bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2321bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2322bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2323bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
23246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2325545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2326cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
23274ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
23284ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
23294ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
23307a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
23314ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
23324ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
23334ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
23344ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
23354ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2336cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
23376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2339bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2340cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
234149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
23424ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
23434ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
23444ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
234549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
234649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2347396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
23484ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
23494ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2350396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2351396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2352396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2353cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2354cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2355cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2356cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
2357cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2358cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2359cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
2360cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
23616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2362fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2363d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2364bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2365fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2366bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2367bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2368bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
23691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2370fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2371fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2372fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2373fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
23741731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2375fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
23761731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2377fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2378fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2379fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
23800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2381fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2382fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2383210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
23845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2385fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2386fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2387210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2388210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2389fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2390fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2391fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
239273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2393210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2394fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
239573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
239673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
239773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
239873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
239973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
240073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
240173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
240273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
240373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
240473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
240573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
240673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
240773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
240873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
240973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
241073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2411fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2412fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2413fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2414fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2415210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
24160b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2417210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
24180b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
2419fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2420fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2421210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
24220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2423fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2424fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2425fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2426fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2427162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2428fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2429fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2430fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2431fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2432fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2433fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2434fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2435fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
243673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2437183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
243873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
243973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
24402ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
244173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
244273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
244373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
244473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
244573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
244673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
244773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
244873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
244973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2450390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2451390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2452390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2453390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2454f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2455f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2456fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2457fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2458fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
24593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2460fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2461fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
24623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2463fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2464fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
246573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
246673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
246773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
246873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2469fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
24700b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2471fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
24720b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2473fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2474fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
247573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
247673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
247773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
247873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2479fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
24800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2481fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
24820b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2483fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2484fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2485fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
24860b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2487fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
24880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2489fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
24900b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2491fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2492fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2493fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
24940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2495fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2496aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2497aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2498aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2499aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2500fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2501aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2502aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2503aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2504aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2505fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
250673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
250773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
250873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2509f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2510f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2511f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2512f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2513f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2514f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2515f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2516f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2517f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
251873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2519fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2520fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
252173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
252273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2523fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2524fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2525fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2526162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2527ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2528a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2529ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2530fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2531fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
25320744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
25331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2534d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
25351731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2536d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2537e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
253887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2539d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2540883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2541d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2542d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2543bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
254487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2545d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2546d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
25471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25485bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
25491731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
25505bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
25511731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2552bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
255387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
25545bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2555883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
25565bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
25575bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2558bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
255987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
25605bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
25615bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
25621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
25631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
25647255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
25651731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
25667255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
25671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25687255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
256987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
25707255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2571883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
25727255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
25737255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
25747255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
257587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2576f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
25777255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
25787255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
25791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2580ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2581ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2582831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2583ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2584ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2585ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2586ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
258787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2588ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2589883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2590ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2591ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2592ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
259387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2594ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2595ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2596ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2597ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2598ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
25991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2600ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2601ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2602ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2603ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2604ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2605ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2606ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
260787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2608ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2609883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2610ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2611ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2612ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
261387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2614ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2615ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2616ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2617ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2618ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
26191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2620ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2621ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
26221731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2623ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2624ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
262587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2626ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2627883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2628ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2629ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2630ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
263187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
26322c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2633723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
26342c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
26352c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
26362c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
26372c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
26382c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
26392c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
26402c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
26412c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
26422c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
26432c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
26442c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
26452c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
264687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2647ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2648ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2649ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2650ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2651ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
26521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2653ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2654ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
26551731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2656ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
26571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2658ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
265987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2660ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2661883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2662ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2663ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2664ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
266587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2666ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2667ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2668ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2669ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2670ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
26711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2672ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2673ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
26741731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2675ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
26761731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2677ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
267887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2679ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2680883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2681ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2682ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2683ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
268487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2685ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2686ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2687ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2688ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2689ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
26901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
269126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
26921731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
269326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2694bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
269587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2696c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
269726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2698883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
269926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
270026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2701bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
27020130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2703cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2704c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2705c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2706bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
270787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
270826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
270926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
27101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
271187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2712711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
271387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2714e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2715711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
271687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
2717711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2718e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
271987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
272087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
272187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2722711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2723711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2724711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
272587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2726e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
272787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2728e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2729e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
273087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2731e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2732f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
273387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
273404633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2735e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
273687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2737e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
273852fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
273987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
274052fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2741414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
274287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
2743414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
27445cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
274587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2746414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
274787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2748414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2749414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2750414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
27515f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2752414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2753414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2754414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2755414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2756414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2757414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
275887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
275987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2760414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2761414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2762414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
276387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PcsAttr(Attr.getLoc(), S.Context, PCS));
2764414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2765e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2766e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2767e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2768e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2769e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2770e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
27711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
277256aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
277387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2774f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2775f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2776711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2777711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2778711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2779711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2780831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
2781831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2782831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
2783711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2784711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2785711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2786ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
278755d3aaf9a537888734762170823daf750ea9036dEli Friedman
2788414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
2789414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
2790711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2791711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
2792711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2793711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2794711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2795711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2796414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2797414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2798414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
27995cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
2800414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2801414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2802414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2803414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
2804414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2805414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
28065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2807414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
2808414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
2809414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2810414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
2811414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
2812414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2813414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2814414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
2815414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2816711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
2817711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2818711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2819711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2820711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2821711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
28221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
282387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2824711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2825711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
282687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
2827711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2828711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
282987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
283087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
283187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2832ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2833ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
283455d3aaf9a537888734762170823daf750ea9036dEli Friedman
283587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, numParams));
2836711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2837711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2838711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
2839711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
284087c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
284187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
2842711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2843711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
284487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
284587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
284687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2847711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2848711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2849711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
285087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
285155d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2852ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2853711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
285487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
285555d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
285687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2857711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
285855d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
285955d3aaf9a537888734762170823daf750ea9036dEli Friedman
2860711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (Context.Target.getRegParmMax() == 0) {
286187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
286255d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
286387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2864711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
286555d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
286655d3aaf9a537888734762170823daf750ea9036dEli Friedman
2867711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
2868711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (numParams > Context.Target.getRegParmMax()) {
286987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2870711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
287187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2872711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
287355d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
287455d3aaf9a537888734762170823daf750ea9036dEli Friedman
2875711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2876ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2877ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
28781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
28797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
28807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
28817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
2882bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
2883bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
28847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
28857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
28867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
288787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
28887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2889883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
28907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
28917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
28927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
28937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
28947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
28957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
28967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
28977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
28987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
28997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
29007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
29017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
29027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
29037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
29047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
29057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
29067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
29077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
29087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
29097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
29107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
29117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
29127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
29137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
29147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
291587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
29167b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
29177b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
29187b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
29197b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
29207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
29217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
29227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
29230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
2924b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
2925b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
2926b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2927c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
2928c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
2929c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2930c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
2931c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
2932c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2933c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
29341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
293587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
2936c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
293787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
293887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedParameter;
2939c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2940c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2941c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2942c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
294387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
2944c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
2945c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2946c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
2947c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
2948c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2949c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2950c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2951c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
295287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
295387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << cf;
2954c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2955c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2956c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2957c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
295887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getLoc(), S.Context));
2959c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
296087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getLoc(), S.Context));
2961c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2962c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
29631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
29641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
296587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
296687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
296787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedMethod;
2968c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2969c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2970c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
297187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getLoc(), S.Context));
2972c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2973c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
29741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
29751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
2976b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2977c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
2978bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
297987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2980c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
298187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
2982831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
298387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
298487c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
2985f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
298687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
2987c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
29885dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
298987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
299087c44604325578b8de07d768391c1c9432404f5aChandler Carruth        << SourceRange(Attr.getLoc()) << Attr.getName()
2991883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
2992b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
2993b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
2994bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2995c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
2996c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
299787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2998c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
2999c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3000c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3001c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3002c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3003c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3004c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3005c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3006c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3007c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3008c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3009c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3010c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3011c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3012c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3013c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
301487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
301587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc())
301687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3017bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
30185dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3019bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
302087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3021b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3022b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
3023b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3024c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
302587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getLoc(),
3026c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3027c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
302831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
302987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(),
3030f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
303131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
303231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
303387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(),
3034f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
303531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3036b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
303787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(),
3038f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3039b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3040b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
304187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(),
3042f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3043b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3044b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3045b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3046b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3047dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3048dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3049dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3050dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3051dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3052dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3053dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!isa<ObjCMethodDecl>(method)) {
3054dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type)
3055dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc, loc) << attr.getName() << 13 /* methods */;
3056dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3057dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3058dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3059dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3060dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3061dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!resultType->isPointerType() || resultType->isObjCRetainableType()) {
3062dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3063dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3064dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3065dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3066dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3067dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3068dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3069dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3070dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3071dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    ::new (S.Context) ObjCReturnsInnerPointerAttr(loc, S.Context));
3072dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3073dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
30741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
30751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
307687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3077f85e193739c953358c865005855253af4f68a497John McCall
307887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  SourceLocation L = Attr.getLoc();
307987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
308087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
3081f85e193739c953358c865005855253af4f68a497John McCall}
3082f85e193739c953358c865005855253af4f68a497John McCall
30831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
30841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
308587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
308687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    SourceLocation L = Attr.getLoc();
308787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
308887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
3089f85e193739c953358c865005855253af4f68a497John McCall    return;
3090f85e193739c953358c865005855253af4f68a497John McCall  }
3091f85e193739c953358c865005855253af4f68a497John McCall
309287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3093f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3094f85e193739c953358c865005855253af4f68a497John McCall
3095f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3096f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
309787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3098f85e193739c953358c865005855253af4f68a497John McCall      << type;
3099f85e193739c953358c865005855253af4f68a497John McCall    return;
3100f85e193739c953358c865005855253af4f68a497John McCall  }
3101f85e193739c953358c865005855253af4f68a497John McCall
3102f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3103f85e193739c953358c865005855253af4f68a497John McCall
3104f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3105f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3106f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3107f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3108f85e193739c953358c865005855253af4f68a497John McCall
3109f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3110f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3111f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3112f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3113f85e193739c953358c865005855253af4f68a497John McCall    break;
3114f85e193739c953358c865005855253af4f68a497John McCall
3115f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3116f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3117f85e193739c953358c865005855253af4f68a497John McCall    break;
3118f85e193739c953358c865005855253af4f68a497John McCall
3119f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3120f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
312187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3122f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3123f85e193739c953358c865005855253af4f68a497John McCall    break;
3124f85e193739c953358c865005855253af4f68a497John McCall  }
3125f85e193739c953358c865005855253af4f68a497John McCall
312687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
312787c44604325578b8de07d768391c1c9432404f5aChandler Carruth                 ObjCPreciseLifetimeAttr(Attr.getLoc(), S.Context));
3128f85e193739c953358c865005855253af4f68a497John McCall}
3129f85e193739c953358c865005855253af4f68a497John McCall
3130f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
3131f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
313211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
313311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
313411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
313511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
313611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
313711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
313811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
313911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
31401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
314111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
314211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
31431731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
314411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
31451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
314611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
314711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
31485cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3149d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3150d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3151d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3152d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3153d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
31545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3155d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3156d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3157d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3158d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3159d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3160d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3161d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3162d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3163d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3164d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3165d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3166d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3167d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3168d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3169d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3170d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
31715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3172f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3173f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3174f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3175f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3176d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3177d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3178d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3179d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3180d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3181d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3182d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3183d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3184d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3185d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3186d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
318711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
318887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
318911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3190d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
319111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3192f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3193f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3194b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
31950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
31960744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
31970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
31981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
31991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
320060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
32011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
32021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
32031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
320460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
320560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
320660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
320760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3208e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
32091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
32101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3211803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
32121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break;
32131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
3214857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
32151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3216803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3217207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3218ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
32196e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
32204211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
32214211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3223bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3224803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
322560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
322660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
322760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
322860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
322960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
323060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
32311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
32321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3233bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
32341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3235b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
32361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
32371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
32381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3239bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
32401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
32411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
32421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
32431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
32441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
32451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
32463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
32471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
32483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
32491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
32501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
32511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
32521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
32537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
32541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
32557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
32561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
32571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
32581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
32591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
32601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3261dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3262dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3263dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
32641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
32651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
32661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
32671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
32681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
32691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3270b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3271b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
32721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3273f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
32741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3275f85e193739c953358c865005855253af4f68a497John McCall
3276dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3277dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3278dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3279b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3280c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
32811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3282c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
32831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3284c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3285c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
328631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
328731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3288b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3289b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
32901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3291b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
32926f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
32931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
32946f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3295521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
32961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3297521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
32981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
32991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break;
33001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
33011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3302742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  case AttributeList::AT_arc_weakref_unavailable:
3303742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3304742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
33051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
33061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
33071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
33081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3309026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
33101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
33111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
33121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3313803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
33141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3315803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
33160db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
33171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
33180db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3319d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
33201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3321d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
33221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break;
33231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
33241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
33251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
33261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
33271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
33281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
33291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
33301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
333205f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
333305f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
33347255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
33351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
33367255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
333704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
333804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
333904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3340f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
334152fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3342414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
33431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
334404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3345f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
33461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3347f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
334811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
33491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
335011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3351fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3352fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3353fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3354fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3355fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3356fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3357fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3358fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3359fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3360fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3361fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3362fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3363fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3364fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3365fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3366fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3367fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3368db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3369db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3370db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3371db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3372db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3373db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3374db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3375db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3376db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3377db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3378db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3379db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3380db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3381db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3382db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3383db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3384db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3385db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3387db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3388db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3389db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3392db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3393db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3394db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3395db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3396db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3397db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3398db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3399db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3400db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3401db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3402db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3403db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3404db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3405db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3406db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3407fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3408803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
340982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
341082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
341182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
34127d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
34137d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3414803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3415803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3416803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3417803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
341860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
341960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
342060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
342160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
34221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
34231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
342460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
342560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
342660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
342760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
342860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
342960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
343060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
343160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
343260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
34331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
343460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
343560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
34361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
343760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
343860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3439803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3440803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3441f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
344260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
344360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
344411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
34451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
344611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
344711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
344811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
344911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
345011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
345160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
345211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3453dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
345411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3455803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3456803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3457803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
3458e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3459e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
34601eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
34617b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3462e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3463e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3464e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3465ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                FD->getInnerLocStart(),
3466e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
3467a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
3468b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
3469b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
3470c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3471b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3472e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3473e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3474ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3475a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
347616573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
347716573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3478b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3479b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3480c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3481b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3482e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3483e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3484e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3485e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3486e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3487e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
34887b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3489c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3490c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3491c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3492c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3493c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
3494cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3495cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3496cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3497c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3498c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3499c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3500c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3501c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3502c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3503c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3504c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3505cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3506e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3507e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3508e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
35090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
35100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
35110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
351260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
351360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3514d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3515d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
351631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
351731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
351831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
351931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
352031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
352131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
352231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
352331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
352431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
352531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
352631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
352731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3528d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3529e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3530e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3531e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3532e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
35330744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
35347f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
353560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3536bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
35370744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
35380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
35390744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
35400744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
35410744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
35420744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
354360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3544bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
35450744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
35460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
354760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
35480744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
354954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3550f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3551f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3552f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3553f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3554f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3555f85e193739c953358c865005855253af4f68a497John McCall  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl))
3556f85e193739c953358c865005855253af4f68a497John McCall    return false;
3557f85e193739c953358c865005855253af4f68a497John McCall
3558f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3559f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3560f85e193739c953358c865005855253af4f68a497John McCall}
3561f85e193739c953358c865005855253af4f68a497John McCall
3562f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
3563f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3564f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
3565f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
3566f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3567f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
3568f85e193739c953358c865005855253af4f68a497John McCall    return;
3569f85e193739c953358c865005855253af4f68a497John McCall  }
3570f85e193739c953358c865005855253af4f68a497John McCall
3571f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3572f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3573f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
3574f85e193739c953358c865005855253af4f68a497John McCall}
3575f85e193739c953358c865005855253af4f68a497John McCall
3576eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3577eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3578eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3579eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3580eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3581eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3582eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3583eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3584eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3585eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3586eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3587eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3588eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3589eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3590eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3591eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3592eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3593eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3594eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3595eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3596eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
359754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
359854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3599eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3600eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
3601eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
360254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3603eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
3604eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
3605eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
3606eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
360754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3608eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
3609eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
361054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3611eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
3612eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
3613eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
361458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
36152f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
36162f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
3617a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis  if (decl && !decl->isInvalidDecl()) {
3618eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
3619eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
36202f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
36212f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
36222f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
36232f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
36242f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
3625eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3626eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
3627eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
36282f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
36292f514480c448708ec382a684cf5e035d3a827ec8John McCall
3630eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
36312f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
3632eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
36332f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
36342f514480c448708ec382a684cf5e035d3a827ec8John McCall
36352f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
3636eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
36372f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
3638f85e193739c953358c865005855253af4f68a497John McCall
3639f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
3640f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
3641f85e193739c953358c865005855253af4f68a497John McCall        break;
364254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
364354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
364454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
364554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
364658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
3647eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
364829233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
364958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
3650eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
36512f514480c448708ec382a684cf5e035d3a827ec8John McCall}
36522f514480c448708ec382a684cf5e035d3a827ec8John McCall
36532f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
36542f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
36550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
36562f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
36572f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
36582f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
36592f514480c448708ec382a684cf5e035d3a827ec8John McCall}
36602f514480c448708ec382a684cf5e035d3a827ec8John McCall
36619c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
36622f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
36632f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
36642f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
36652f514480c448708ec382a684cf5e035d3a827ec8John McCall
36662f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
3667ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
3668c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
3669ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
3670ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
3671c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
3672c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
3673ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
367454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
367554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
36765f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
36778e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
367889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
367954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
3680eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3681eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
368254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
368354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
368454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
368554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
368654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
368754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
3688ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
3689c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3690c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
36918e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
3692743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
36938e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
369489ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
36958e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
369689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
369789ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
36988e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
369954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
3700