SemaDeclAttr.cpp revision b219cfc4d75f0a03630b7c4509ef791b7e97b2c8
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"
18b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski#include "clang/AST/DeclTemplate.h"
19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
20acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
21f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h"
22fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2319510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
25797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
279c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of
30883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
31b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskienum AttributeDeclKind {
32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunction,
33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedUnion,
34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableOrFunction,
35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionOrMethod,
36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameter,
37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameterOrMethod,
38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrBlock,
39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassOrVirtualMethod,
40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrParameter,
41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClass,
42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVirtualMethod,
43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassMember,
44883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariable,
45883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedMethod,
46db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  ExpectedVariableFunctionOrLabel,
47db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  ExpectedFieldOrGlobalVar
48883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall};
49883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall
50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
52e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
53e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
5487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D,
55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
5787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
6187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
65bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
68755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
696217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
70d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
71183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
77d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
78a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
7987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) {
8087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return getFunctionType(D, false) != NULL;
81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
82a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
83a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
84d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
85d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
8687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) {
8787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isFunction(D)|| isa<ObjCMethodDecl>(D);
88d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
893568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
9387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
9487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isFunctionOrMethod(D))
95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
9787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
10187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<BlockDecl>(D);
102620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
103620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
104711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
105711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
10687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) {
107f85e193739c953358c865005855253af4f68a497John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
10887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
10987c44604325578b8de07d768391c1c9432404f5aChandler Carruth         isa<ObjCPropertyDecl>(D);
110711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
112d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
113d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
114620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
11587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) {
11687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
11772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
118620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
11987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
121d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1233568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
125d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
126d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
12787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) {
12887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
12972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
13087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
131d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
13287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_size();
1333568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1343568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
13687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
13772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
13887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
139d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
1423568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1433568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
14487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) {
14587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
1465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
14787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->getResultType();
1485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
15087c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) {
15187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D)) {
15272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
15487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
155db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
156d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
15787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    return cast<ObjCMethodDecl>(D)->isVariadic();
1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1603568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
16187c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) {
16287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
16507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
16607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
168183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
169b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
171bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
172506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
173506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
175bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
176506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
183085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1846217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
187085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1886217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
189085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
191bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
192085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
193465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
197085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
198085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
199b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May
200b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth                                  unsigned int Num) {
2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (Attr.getNumArgs() != Num) {
2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    return false;
2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  }
2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  return true;
2091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth}
2101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
211db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
212b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May
213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
215b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                  unsigned int Num) {
216b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (Attr.getNumArgs() < Num) {
217db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return false;
219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  return true;
222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
223db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
224db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski///
225fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var
226fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable
227fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
22839997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) {
229fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (isa<FieldDecl>(D))
230fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return true;
23139997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const VarDecl *vd = dyn_cast<VarDecl>(D))
232fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
235fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
236fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
237b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool.
238b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) {
239b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = Exp->getType();
240b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return QT->isBooleanType() || QT->isIntegerType();
241b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
242b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
243fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
244fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type.
245fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message.
246fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise
247fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
24839997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool checkIsPointer(Sema &S, const Decl *D, const AttributeList &Attr) {
24939997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
250fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
25139997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer    if (QT->isAnyPointerType())
252fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
253fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_pointer_attribute_wrong_type)
254fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
255fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
256fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
257fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
258fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
262b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points
263b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit.
2647d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) {
2657d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const RecordType *RT = QT->getAs<RecordType>())
266b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return RT;
2677d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2687d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  // Now check if we point to record type.
2697d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const PointerType *PT = QT->getAs<PointerType>())
2707d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer    return PT->getPointeeType()->getAs<RecordType>();
2717d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2727d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  return 0;
273b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
274b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
2753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType
2763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// resolves to a lockable object. May flag an error.
277d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramerstatic bool checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
278d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer                                   const RecordType *RT) {
2793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // Flag error if could not get record type for this argument.
280d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT) {
2813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_class)
2823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      << Attr.getName();
2833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return false;
2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // Flag error if the type is not lockable.
286d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT->getDecl()->getAttr<LockableAttr>()) {
2873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_lockable)
2883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      << Attr.getName();
2893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return false;
2903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  return true;
2923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
294b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
295b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// from Sidx, resolve to a lockable object. May flag an error.
2963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with.
2973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function
2983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list.
2993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskistatic bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         const AttributeList &Attr,
3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         SmallVectorImpl<Expr*> &Args,
302b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
303b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
3043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
305b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
3063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
307ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    if (ArgExp->isTypeDependent()) {
308ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      // FIXME -- need to processs this again on template instantiation
309ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      Args.push_back(ArgExp);
310ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      continue;
311ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    }
312b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
314b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
317b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
321b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
322b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
323b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
324b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
3253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
328b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
329b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
330b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          return false;
331b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
3323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
3333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        RT = getRecordType(ArgTy);
334b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
335b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
336b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (!checkForLockableRecord(S, D, Attr, RT))
338b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return false;
339b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
341b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
342b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return true;
343b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
344b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
345e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
346e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
347e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
348e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
3493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
3503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
3513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
3523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
353fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
354fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
355fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
356fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
357fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
358fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
359fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
360fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
361fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
362fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
363b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
364fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
365fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
366fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
367fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
368fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
369fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
370fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
371768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
372fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
373768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
374fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
375fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
376db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
377b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
378db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
379db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
380b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
381db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
382db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
3833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
3843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
385db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
387db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
388b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
389db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
392db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
393db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
394db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
3953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
396ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    // FIXME: handle attributes with dependent types
3973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return;
3983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
4003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType())))
401b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
402b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
403db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
404768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
4053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 S.Context, Arg));
406db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
407768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
408db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
409db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
410db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
411fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
412fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
413fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
414fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
415fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
416fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4181748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
419fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
420fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
421fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
422fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
423fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
424fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
425fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
426768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
427fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
428768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
438b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
440fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
444768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
446fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
448db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
449db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
450db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
451db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
452b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
453db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
455db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
456b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
457b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
458db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
459b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
460db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
462db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
463b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // Check that this attribute only applies to lockable types
464b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
465b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
466b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
467b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
468b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      S.Diag(Attr.getLoc(), diag::err_attribute_decl_not_lockable)
469b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
470b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
471b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
472b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
473b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
475b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
4763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
477b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
478b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
4803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
4813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
4823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
483db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
484768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
4853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                    StartArg, Size));
486db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
487768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
4883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                   StartArg, Size));
489db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
491db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
492b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
493db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
494db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
495db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
496db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
497b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
498b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
499db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
500db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
501db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
502db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
503db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
504b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
5063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
507b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
508b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
514768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
5153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
5163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
517db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
518768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
5193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        S.Context, StartArg,
5203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        Size));
521db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
522db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
524b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
525db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
526db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
527b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
528db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
529db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
530b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
531b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
532db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
533db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
534db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
535db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
537b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
538b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
539b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
540b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
541b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
542b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 2> Args;
544b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1))
546b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
547b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
551db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
552768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
5533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              S.Context,
55469f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                              Attr.getArg(0),
5553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              StartArg, Size));
556db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
557768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
55869f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           S.Context,
55969f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           Attr.getArg(0),
56069f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           StartArg, Size));
561db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
562db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
563db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
564b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
565db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
566db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
567b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
568db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
569db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
570b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
571db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
572db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
573db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
574db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
575db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
576b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
5783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
579b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
580b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
586768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
5873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            S.Context, StartArg,
5883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            Size));
589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
590768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
5913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         S.Context, StartArg,
5923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         Size));
593db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
594db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
595db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
596b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
597db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
598db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
599db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
600db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
601b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
602db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
603db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
604db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
605db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
606db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
607b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
6093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
610b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
611b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
616768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
6173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
620db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
621b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
622db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
623db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
624b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
625db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
6263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
627db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
628b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
629db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
630db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
631db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
633db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
635b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
636b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
6383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType())))
6393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return;
6403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
641768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg));
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
645b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
646db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
647db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
648b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
650db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
651b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
652db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
656db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
657b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
6593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
660b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
661b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
666768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
6673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
668db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
670db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
6721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
67387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
674545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
675803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
676545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
6776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
678bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
6809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6819cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
6829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
6849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
685f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
686f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
687f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
6884ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
6894ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
6904ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
6914ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
6924ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
6934ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
6949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
6959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
6961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
6979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
6981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
6997a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
7006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7019cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
7039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
7049ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
7059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
706ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
707a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
708bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7099cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
7109cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
7116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
7161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
7176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
718bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
71987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
720768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
72187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
7226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
7236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
7246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
725803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
726fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
72708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
7286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
729768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
7306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
7313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
7326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
73587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
736768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
737c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
738c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
739c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
740c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
7411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
74296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
7431731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
74496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
745bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
74663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
74787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
74863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
749768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
75063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
75163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
75263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7534ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
75463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
75563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
75763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
7581731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
75963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
76063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
76163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
762efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
76387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D)) {
764768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
76563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
766efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
76763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7684ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
76996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
77096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
7711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
7721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
773857e918a8a40deb128840308a318bf623d68295fTed Kremenek
774857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
775a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
776857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
777857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
778857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
779857e918a8a40deb128840308a318bf623d68295fTed Kremenek
780857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
781857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
78287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!(isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
7834ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
784857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
785857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
78687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
7873a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
7883a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
7893a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
7903a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
7913a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
79287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7933a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
7943a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
7953a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
7963a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
7973a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
7983a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
799a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
800a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
801a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
8023a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
803b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
80487c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
805a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
806a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
807a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
808a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
809b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
810a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
811a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
812a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
813a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
814a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
815a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
816a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
817a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
818a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
819f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
820f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
821857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
822857e918a8a40deb128840308a318bf623d68295fTed Kremenek
823d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
82468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
82568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
82668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
82768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
82868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
82968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
83068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
83168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
83268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
83368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
83468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
83568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
83668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
83768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
8381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
839bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
840bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
84187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
842fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
843883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
844eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
845eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
846bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
84707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
84807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
84987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
85087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
851eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
852eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
8535f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
854bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
855eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
856eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
857bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
858bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
859eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
8607a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
861eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
862ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
863ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
864fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
865fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
866eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
867eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
868bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
869eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
870bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
871eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
872fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
87330bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
874eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
875eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
876bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
877465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
87807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
87907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
88007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
88107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
88207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
88307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
88407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
88507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
88607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
887eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
888eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
88987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
890d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
89168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
892dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
893eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
894c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
895fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
8967fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
897eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
898bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
899eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
900eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
901bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
902bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
903bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
9047fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
90587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
90687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
907d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
908dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
909d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
91046bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
911bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
912ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
91360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
91460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
91560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
91660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
91760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
9187fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
91960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
920eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
9217fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
9227fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
9237fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
924dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
925768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
926cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
927eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
928eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
9291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
930dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
931dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
932dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
933dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
934dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
935dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
9362a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
9372a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
938dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
939dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
940dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
941dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
942dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
943dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
944dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
945cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
9462a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
9472a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
948cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
949dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
950dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
951dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
952dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9532a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9542a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
955cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
956dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
959dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9602a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9612a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
962cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
963dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
964dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
965dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
966dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
967dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9682a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9692a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
9702a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
9712a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
972dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
973dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
97487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
975883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
976883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
977dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
978dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
979dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
98007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
98107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
98287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
98387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9855f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
986dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
987dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
988dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
989dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
990dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
992dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9932a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
9942a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
995dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
997dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
998dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
999dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1000dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1002dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1004dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1008dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1009dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1010dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1011dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1012dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
101307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
101407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
101507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
101607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
101707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
101807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
101907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
102007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
102107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1022dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1023cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1024cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1025dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
102687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1027dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1030cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1031dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1032dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1033dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1034dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1035dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1036dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1037cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
10407a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1041dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1042dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1043dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1044dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1045dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1046dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1047dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1048dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1049dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
10522a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
10532a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1055dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1056dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1057cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
105887c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
105987c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1060cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1061cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1062cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1063cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1064cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1065cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1066cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1067dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1068dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1069dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1070dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1072dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1073dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1074dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1075dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1077cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1078cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1079cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1080cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1081dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1082cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
108387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1084cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1085dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1086dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1087332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1088332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1089332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1090332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1091332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1092332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1093332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1094332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1095332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1096332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1097332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1098332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1099332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1100332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1101332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1102332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1103332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
110411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
110511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
110611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
110811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
110911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
111011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
111111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
111211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
111311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
111487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1115332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1116883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1117332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1118332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1119332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
112087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1121332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
112211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
112311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
112411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
112511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
112611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
112711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
112811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
112911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
113011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
113111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
113287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
11337a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
11347a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1135332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
11367a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
113711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
113811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
113911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
114011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
114111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
114211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
114311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
114411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
114511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
114611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
114711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
114811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
114911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
115011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
115211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1157332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1158332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
115911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
116011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
116111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
116211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
116411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
116611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
11677a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11715cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
117311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
117411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
117711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1178768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1179f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
118011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
118111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1182768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
118311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
118411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
11866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1187545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
11883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1191bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11927a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
11936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
11946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1195bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11965cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1197fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
11983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
11996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1201bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1202bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1203f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1204f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1205f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1206f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
12076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1208bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1209768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1210f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
12116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1214dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
12151731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1216dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1217dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
121887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1219dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1220883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1221dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1222dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1223dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1224768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1225dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1226dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
12271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
12281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1229dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1230831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
12313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1232af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1233af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
12345bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
123587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
12365bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1237883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
12385bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
12395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1240bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1241768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1242af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1243af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
12441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1245dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1246831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
124776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
124876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
124976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
12501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
125187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
12532cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1254768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
12552cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
12562cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1257fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1258fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
12592cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
126076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
126176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
12621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
126334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
12641731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
126534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
126634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1267768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
126834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
126934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
12701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
127156aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
127287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1273768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1274722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1275722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1276883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1277a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1278a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
128056aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
128187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1282768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1283722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1284722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1285883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1286a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1287a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
128987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1290711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1291711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1292711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
129387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1294711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1295883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1296711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1297711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1298711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1299768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1300711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1301711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1302711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1303831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1305711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1307711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1308711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1309711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1310b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1311b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
13131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1314b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1315b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1316b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1317b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
13191731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1320b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
132187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
132287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
13233ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
13243ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1325e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1326e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1327b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1328883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1329b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
133019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
13316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1332b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1333768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
13346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
133635cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
13371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
133835cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
133935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
134035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1341f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1342f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1343f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1344f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1345f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
134635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
134735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
134835cc9627340b15232139b3c43fcde5973e7fad30John Thompson
134935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
135035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
135135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
135235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
135335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
135435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
135535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
135635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
135735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
135835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
135935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
136035cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
136187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
136235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1363883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
136435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
136635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
136787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
136835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
136935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
137035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
137135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
137301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
137401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
137501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
137601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
137701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
137801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
137901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
138001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
138101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
138201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
138301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
138401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1385f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1386f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
138701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
138801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
138901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
139001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
139101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
139201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
139301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1394768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
139535cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
139635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
13971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
139887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1399bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1400883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1401bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1402bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1403bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1404bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1405bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
14061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
140773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1408831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
141073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
141173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1412bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
141387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
141487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1415fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1416883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
141773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
141873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1419bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1420768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
142173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
142273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
14231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1424b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1425831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1426b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1427b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1428b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1429bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
143087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1431186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1432b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1433b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1434b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
143587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1436b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1437883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1438b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1439b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1440bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1441768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1442b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1443b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
14441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1446bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1447bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1449bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14537a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1455ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1456ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1457fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
14593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
14603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
14613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
14623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1463bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
146487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1465fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1466883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
14673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
14683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
14693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1470768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1471f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
14723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
14733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1476bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1477bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1479bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14837a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1485ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1486ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1487fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
14893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
14903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
14913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
14923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1493bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
149487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1495fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1496883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
14973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
14983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
14993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1500768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1501f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
15023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1505951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1506951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1507bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1508c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1509c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1510951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1511c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
15125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1513951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1514951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1515c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1516951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1517951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1518c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1519c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1520951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
15216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1522bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1523768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str));
15246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1527951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1528951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1529bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1530bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1531bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1532951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1533c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
15345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1535951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1536951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1537c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1538951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1539c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1540c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1541c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1542951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1543c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1544768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str));
1545bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1546bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1547742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1548742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1549742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1550742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1551742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1552742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1553742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1554742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1555742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1556768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1557742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1558742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
15591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
15601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
15610a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
15620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
15630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
15650a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
15660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
15670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
15680a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
15690a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15700a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
15710a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15720a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15730a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
15740a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
15750a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1576b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
15770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1578c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
15790a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
15800a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
15813b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Deprecated.Version)) {
15820a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
15830a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
15840a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
15850a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
15860a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15880a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
15893b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Obsoleted.Version)) {
15900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
15910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
15920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
15930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
15940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
15973b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Deprecated.Version <= Obsoleted.Version)) {
15980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
15990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
16010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1604768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context,
16050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
16060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
16070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1608b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1609b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                IsUnavailable));
16100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
16110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
16141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
16156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1616bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16177a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
16186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
16196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1620bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16215cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1622fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
16233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
16246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1626bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16275f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1628cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1629bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1630c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1631cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1632c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1633cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1634c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1635cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1636c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1637cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
16386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
163908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
16406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1642bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1643768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type));
16446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
16456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
16471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1648d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1649d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
165087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1651883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1652d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1653d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1654d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
165587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
165687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
165787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1658d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1659d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
166087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1661d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
166287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1663d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1664d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1665d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
16665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1667d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1668d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1669d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1670d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1671d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1672d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1673d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1674d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1675d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1676d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1677d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1678d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1679d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1680d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1681d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1682d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
168387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1684d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1685d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1686d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1687f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1688f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1689f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1690f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1691f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1692f85e193739c953358c865005855253af4f68a497John McCall    return;
1693f85e193739c953358c865005855253af4f68a497John McCall  }
1694f85e193739c953358c865005855253af4f68a497John McCall
1695768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
1696f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1697d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1698d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
16991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
17001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
17011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
17020db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1703bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
17050db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
17060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
17070db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
17080db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1709bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1710768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
17110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
17120db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
17131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1714fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
17152b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1716fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1717fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1718162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1719fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1720fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
17216217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1722fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1723fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1724fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1725fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1726768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
1727fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1728fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1729bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
17301b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1731f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
17322b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1733f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1734f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1735f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1736f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1737f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1738f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1739f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1740f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1741768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
1742f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1743f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
17441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1745bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1746fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
17473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
17489eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
17499eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1750bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17519eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
17523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
17539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
17549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1755bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1756cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
175792e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
17589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
17599eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1760fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
17613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
17629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
17639eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1764bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1765768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
17669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
17679eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
17681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1769770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1770770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1771bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1772770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1773bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1774bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17753323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
1776770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
17777a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1778770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1779ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1780ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1781fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
17823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1783770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1784770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1785bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17863323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
1787fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1788fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1789770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1790770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
17913323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
17923323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
1793770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1794770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
17953323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
1796770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
17977a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1798770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1799ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1800ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1801fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1803770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1804770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1805770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1806bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18073323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
1808770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1809770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1810fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1811fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1812770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1813770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1814770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1815770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
181687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
18173323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
1818897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1819897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1820897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1821897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1822bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1823897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
18243bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1825770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
182787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1828770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
18293bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1830770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
18312f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
183287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (isa<BlockDecl>(D)) {
1833bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1834bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
18352f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
183687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
18372f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1838daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
183987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1840f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
18412f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
18423bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
18433bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
18442f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
18452f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1846ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
18472f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1848883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
18492f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
18502f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1851770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1852fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1853883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1854770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1855770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1856768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
1857f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1858770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1859770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
18601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1861026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
18621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1863026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1864026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1865f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1866026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1867883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1868026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1869026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1870bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1871f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1872f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1873f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1874f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1875f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1876f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1877f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1878f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1879f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1880f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1881f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1882f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1883768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
1884026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1885026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
18861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
188887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
188987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
18906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
189387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
189487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
189587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1896f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1897f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1898f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
189987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1900332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1901332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1902332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
190387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
19046e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1906bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1907768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
19086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
19121731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
19136e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
19156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19166e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
19176e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
19180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
19190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
19200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
19210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
19220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
1923def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1924bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
1925def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor              isa<ObjCInterfaceDecl>(D))) {
1926def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
1927def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
1928c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1929883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
19306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19326e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
19336e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1934768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
19356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
19366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
19381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
19396f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
19401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
19416f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
19426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
19436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
19446f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
19457a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
19466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1947ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1948ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
19496f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
19506f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
19516f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
19526f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
19536f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
19546f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1955768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
1956cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
19576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
19586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
19596f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
19601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
196117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
19621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
196317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
196417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
196517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
196617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
19677a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1968797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
196917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1970797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
197117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
197217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
19731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1974797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1975bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
1976a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1977a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1978a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1979797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1980797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
19811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1982a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1983a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1984a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1985a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1986a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1987a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1988768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context,
1989f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
199017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
199117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
19926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1995831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
19963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1999b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
200087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2001b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2002ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2003b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2004768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2005b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
20066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2009232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2010831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
20113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2012232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2013232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2014bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
201587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2016b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2017ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2018b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2019768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2020b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2021232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2022232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
20231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2024232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
20251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2026232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2027bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2028768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2029232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2030232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
20311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2032bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2033f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2034f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2035f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2036bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2037f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2038f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2039f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2040f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2041bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
204287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2043bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2044f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2045f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2046f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2047f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2048bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2049f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2050c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2051f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2052f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2053f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2054f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2055f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2056f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2057f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2058f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2059bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2060f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2061f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2062f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2063f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2064f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2065f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2066f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2067f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2068f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2069f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2070f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2071f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2072f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2073f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2074bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
207589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
207689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
207789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
207889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2079b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2080b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2081f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
208289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
208389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
208489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
208589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2086bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2087768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
2088223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
2089f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2090f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2091bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2092bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
20931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20941731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
20955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
20961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
209787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
20985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2099883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
21005b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
210207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
210307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
210407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
210587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
210687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
21075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
210807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
21095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
21107a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
21115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2112ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2113ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
21145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
21155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
21165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2118bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
21205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
21215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
21225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2124bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2126bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
212707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
212807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
212907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
213007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
213107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
213207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
213307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
213407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
213507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
21365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
213787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
21405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
21415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
21425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
21436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
21445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
21455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2146bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
21475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
21485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2149bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
215087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
21515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
21525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
21535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
21546217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
21555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
21565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2157bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
21585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
21595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2160bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2161bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2162768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
216307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
21645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
21655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
21662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
21672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
21682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
21692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
21702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
21713c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
21722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
21732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
21742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
21752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
21762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
21775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
21782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
21792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
21802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
21812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
21822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
21832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
21842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
21852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
21862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
21872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
21882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
21892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
2190cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2191cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
21922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
21932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2194bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2195bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
21963c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
21973c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
21982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
21992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
22002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2201521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2202521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
22031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
22041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
2205521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
2206521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2207521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2208521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2209521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
221087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2211b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2212b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2213b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2214b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
221587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2216b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2217b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2218b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2219b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2220b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2221b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2222b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2223b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2224521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2225521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2226521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2227521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2228521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
22297a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2230b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2231521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2232521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2233521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2234521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2235521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2236521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2237521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2238521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
22399f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2240521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2241521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2242521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2243521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2244521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2245521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2246768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2247f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2248521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2249521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2251bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
22521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
22536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2254545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2255fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
22563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
22576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2260545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
22613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
22626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
226587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2266fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2267883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
227107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
227207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
227387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
227487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
22756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
22766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
22786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
22802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
22812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
22822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
22842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
22853c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22863c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
22873c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
22883c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2290fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
229101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
22926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
22967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2297803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2298ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2299ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2300fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2306fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
23073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
23126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2313bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23144a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
23154a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
231607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
231707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
231807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
23194a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
23204a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
23214a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
23224a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
23231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
232587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
23266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2328085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2329fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2330fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2331085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2332085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
23332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2334390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2335390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2336803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2337390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2338fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2339fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
23406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2341bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
23426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
23436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2344390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2345fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2346fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
23476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
23517a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2352803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2353ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2354ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2355fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
23576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
23616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
236287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
23636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
23646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
236587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
23666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
23676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
23686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
23713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
23722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
23736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2374fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2375fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
23766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
23776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
23786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
23796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2380fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
23813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
23826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2385b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2386b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
238787c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
238887c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2389b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2390b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2391b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2392b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2393b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2394b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2395b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2396b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2397ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis        f->setRange(Attr.getRange());
2398b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2399b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2400b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2401b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
2402768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format,
2403cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
24042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
24056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
24081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
24096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
24101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
24116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24121731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
24136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
24150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
241687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
24170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
24180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
24190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
242087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
24210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
24220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2423fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2424883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
24256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
2429bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
24300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
24310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
24330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
243417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
243517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
24360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
24370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
24380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2440bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
24410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
24420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
244390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2444bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
244590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
244690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
24470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2449bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
24500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
24510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
24520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
24530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
24540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
24550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
24560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
24570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2458bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
24590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2460bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
24610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
24620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
24630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2464bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
24650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
24660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2467bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2468bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2469bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
24706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2471768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
24726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
24761731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
24776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
24797a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2480797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2481bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
24836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
24846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2485797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
24866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
248877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
248977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
249077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
249177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
249277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
249377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
249477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
249577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
2496768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
2497f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
24986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2502545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
25033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
25046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2506bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2507bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2508bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2509bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
25106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2511545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2512768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0));
25134ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
25144ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
25154ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2516768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0));
25174ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
25184ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2519768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
25204ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
25214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2522768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
25236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2525bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2526768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
2527cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
252849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
25294ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
25304ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
25314ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
253249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
253349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2534396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
25354ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
25364ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2537396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2538396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2539396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2540768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
2541cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2542cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2543768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
2544cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2545cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2546768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS));
2547cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
25486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2549fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2550d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2551bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2552fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2553bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2554bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2555bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
25561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2557fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2558fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2559fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2560fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
25611731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2562fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
25631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2564fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2565fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2566fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
25670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2568fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2569fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2570210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
25715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2572fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2573fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2574210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2575210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2576fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2577fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2578fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
257973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2580210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2581fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
258273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
258373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
258473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
258573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
258673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
258773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
258873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
258973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
259073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
259173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
259273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
259373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
259473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
259573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
259673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
259773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2598fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2599fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2600fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2601fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2602210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
2603bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2604210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
2605bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
2606fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2607fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2608210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
2609bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2610fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2611fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2612fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2613fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2614162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2615fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2616fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2617fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2618fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2619fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2620768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
2621fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2622fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
262373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2624183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
262573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
262673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
26272ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
262873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
262973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
263073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
263173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
263273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
263373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
263473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
263573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
263673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2637390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2638390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2639390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2640390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2641f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2642f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2643fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2644fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2645fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
26463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2647fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2648fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
26493c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2650fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2651fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
265273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
265373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
265473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
265573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2656fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
26570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2658fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
26590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2660fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2661fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
266273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
266373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
266473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
266573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2666fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
26670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2668fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
26690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2670fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2671fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2672fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
26730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
26750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2676fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
26770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2678fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2679fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2680fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
26810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2682fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2683bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2684aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2685aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2686aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2687fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2688bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2689aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2690aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2691aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2692fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
269373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
269473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
269573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2696f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2697f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2698f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2699f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2700f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2701f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2702f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2703f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2704f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
270573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
270873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
270973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2710fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2712fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2713162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2714ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2715a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2716ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2717fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2718fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
27190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
27201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2721d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
27221731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2723d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2724e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
272587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2726d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2727883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2728d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2729d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2730bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2731768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
2732d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2733d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
27341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
27355bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
27361731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
27375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
27381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2739bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
274087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
27415bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2742883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
27435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
27445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2745bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2746768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
27475bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
27485bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
27491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
27501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
27517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
27521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
27537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
27541731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
27557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
275687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
27577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2758883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
27597255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
27607255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
27617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2762768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
2763f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
27647255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
27657255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
27661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2767ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2768ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2769831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2770ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2771ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2772ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2773ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
277487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2775ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2776883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2777ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2778ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2779ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2780768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
2781ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2782ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2783ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2784ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2785ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
27861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2787ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2788ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2789ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2790ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2791ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2792ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2793ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
279487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2795ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2796883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2797ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2798ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2799ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2800768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
2801ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2802ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2803ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2804ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2805ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2807ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2808ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2810ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2811ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
281287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2813ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2814883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2815ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2816ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2817ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
281887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
28192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2820723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
28212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
28222c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
28232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
28242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
28252c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
28262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
28272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
28282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
28292c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
28302c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
28312c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
28322c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2833768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
2834ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2835ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2836ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2837ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2838ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2840ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2841ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2843ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
28441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2845ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
284687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2847ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2848883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2849ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2850ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2851ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2852768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
2853ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2854ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2855ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2856ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2857ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2859ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2860ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28611731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2862ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
28631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2864ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
286587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2866ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2867883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2868ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2869ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2870ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2871768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
2872ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2873ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2874ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2875ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2876ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
287826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
28791731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
288026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2881bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
288287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2883c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
288426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2885883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
288626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
288726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2888bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
28890130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2890cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2891c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2892c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2893bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2894768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
289526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
289626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
28971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
289887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2899711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
290087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2901e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2902711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
290387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
2904711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2905e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
290687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
290787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
290887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2909711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2910711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2911711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
291287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2913e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
2914768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
2915e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2916e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
2917768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
2918e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2919f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
2920768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
292104633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2922e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
2923768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
2924e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
292552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2926768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
292752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2928414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
292987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
2930414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
29315cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
293287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2933414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
293487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2935414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2936414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2937414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
29385f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2939414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2940414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2941414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2942414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2943414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2944414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
294587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
294687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2947414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2948414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2949414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2950768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
2951414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2952e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2953e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2954e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2955e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2956e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2957e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
29581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
295956aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
2960768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
2961f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2962f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2963711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2964711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2965711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2966711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2967831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
2968831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2969831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
2970711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2971711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2972711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2973ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
297455d3aaf9a537888734762170823daf750ea9036dEli Friedman
2975414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
2976414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
2977711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2978711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
2979711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2980711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2981711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2982711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2983414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2984414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2985414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
29865cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
2987414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2988414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2989414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2990414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
2991414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2992414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
29935f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2994414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
2995414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
2996414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2997414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
2998414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
2999414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3000414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3001414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3002414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3003711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
3004711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3005711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3006711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3007711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3008711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
30091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
301087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3011711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3012711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
301387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3014711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3015711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
301687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
301787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
301887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3019ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3020ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
302155d3aaf9a537888734762170823daf750ea9036dEli Friedman
3022768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3023711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3024711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3025711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3026711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
302787c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
302887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3029711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3030711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
303187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
303287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
303387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3034711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3035711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3036711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
303787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
303855d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3039ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3040711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
304187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
304255d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
304387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3044711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
304555d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
304655d3aaf9a537888734762170823daf750ea9036dEli Friedman
3047bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
304887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
304955d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
305087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3051711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
305255d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
305355d3aaf9a537888734762170823daf750ea9036dEli Friedman
3054711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3055bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
305687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3057bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
305887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3059711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
306055d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
306155d3aaf9a537888734762170823daf750ea9036dEli Friedman
3062711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3063ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3064ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
30651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
30667b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
30677b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
30687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3069bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3070bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
30717b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
30727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
307487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
30757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3076883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
30777b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
30787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
30807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
30817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
30827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
30837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
30847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
30857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
30867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
30877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
30887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
30907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
30917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
30927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
30937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
30947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
30957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
30967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
30977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
30987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
30997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
31007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3102768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
31037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
31047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
31057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
31067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
31077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
31087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
31097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3111b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3112b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3113b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3114c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
3115c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
3116c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3117c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
3118c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
3119c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3120c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
31211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
312287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3123c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
312487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3125768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3126c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3127c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3128c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3129c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
313087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3131c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3132c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3133c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3134c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3135c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3136c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3137c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3138c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
313987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3140768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3141c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3142c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3143c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3144c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3145768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3146c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3147768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3148c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3149c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
31501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
31511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
315287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
315387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3154768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3155c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3156c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3157c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3158768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3159c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3160c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
31611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
31621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3163b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3164c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3165bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
316687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3167c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
316887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3169831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
317087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
317187c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3172f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
317387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3174c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
31755dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
317687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3177768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3178883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3179b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3180b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3181bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3182c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3183c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
318487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3185c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
3186c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3187c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3188c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3189c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3190c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3191c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3192c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3193c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3194c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3195c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3196c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3197c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3198c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3199c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3200c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
320187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3202768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
32045dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
320687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3207b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3208b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
3209b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3210c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
3211768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3212c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3213c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
321431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
3215768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3216f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
321731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
321831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
3219768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3220f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
322131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3222b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
3223768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3224f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3225b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3226b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
3227768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3228f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3229b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3230b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3231b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3232b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3233dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3234dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3235dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3236dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3237dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3238dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3239dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!isa<ObjCMethodDecl>(method)) {
3240dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type)
3241dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc, loc) << attr.getName() << 13 /* methods */;
3242dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3243dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3244dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3245dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3246dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3247dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!resultType->isPointerType() || resultType->isObjCRetainableType()) {
3248dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3249dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3250dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3251dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3252dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3253dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3254dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3255dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3256dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3257768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3258dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3259dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
32601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
32611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
326287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3263f85e193739c953358c865005855253af4f68a497John McCall
326487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3265768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    << Attr.getRange() << Attr.getName() << 12 /* variable */;
3266f85e193739c953358c865005855253af4f68a497John McCall}
3267f85e193739c953358c865005855253af4f68a497John McCall
32681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
32691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
327087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
327187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3272768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << 12 /* variable */;
3273f85e193739c953358c865005855253af4f68a497John McCall    return;
3274f85e193739c953358c865005855253af4f68a497John McCall  }
3275f85e193739c953358c865005855253af4f68a497John McCall
327687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3277f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3278f85e193739c953358c865005855253af4f68a497John McCall
3279f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3280f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
328187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3282f85e193739c953358c865005855253af4f68a497John McCall      << type;
3283f85e193739c953358c865005855253af4f68a497John McCall    return;
3284f85e193739c953358c865005855253af4f68a497John McCall  }
3285f85e193739c953358c865005855253af4f68a497John McCall
3286f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3287f85e193739c953358c865005855253af4f68a497John McCall
3288f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3289f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3290f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3291f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3292f85e193739c953358c865005855253af4f68a497John McCall
3293f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3294f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3295f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3296f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3297f85e193739c953358c865005855253af4f68a497John McCall    break;
3298f85e193739c953358c865005855253af4f68a497John McCall
3299f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3300f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3301f85e193739c953358c865005855253af4f68a497John McCall    break;
3302f85e193739c953358c865005855253af4f68a497John McCall
3303f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3304f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
330587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3306f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3307f85e193739c953358c865005855253af4f68a497John McCall    break;
3308f85e193739c953358c865005855253af4f68a497John McCall  }
3309f85e193739c953358c865005855253af4f68a497John McCall
331087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3311768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3312f85e193739c953358c865005855253af4f68a497John McCall}
3313f85e193739c953358c865005855253af4f68a497John McCall
3314f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
3315f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
331611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
331711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
331811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
331911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
332011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
332111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
332211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
332311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
33241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
332562ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
332611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
33271731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
332811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
33291731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
333011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
333111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
33325cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3333d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3334d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3335d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3336d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3337d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
33385f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3339d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3340d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3341d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3342d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3343d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3344d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3345d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3346d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3347d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3348d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3349d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3350d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3351d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3352d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3353d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3354d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
33555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3356f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3357f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3358f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3359f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3360d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3361d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3362d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3363d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3364d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3365d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3366d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3367d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3368d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3369d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3370d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
337111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
3372768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
337311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3374d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
337511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3376f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3377f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3378b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
33790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
33800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
33810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
33821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
33831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
338460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
33851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
33861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
33871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
338860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
338960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
339060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
339160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3392e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
33931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
33941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3395803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
33961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break;
33971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
3398857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
33991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3400803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3401207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3402ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
34036e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
34044211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
34054211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3406bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3407bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3408803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
340960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
341060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
341160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
341260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
341360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
341460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
34151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
34161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3417bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
34181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3419b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
34201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
34211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
34221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3423bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
34241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
34251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
34261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
34271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
34281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
34291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
34303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
34311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
34323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
34331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
34341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
34351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
34361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
34377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
34381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
34397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
34401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
34411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
34421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
34431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
34441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3445dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3446dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3447dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
34481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
34491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
34501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
34511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
34521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
34531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3454b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3455b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
34561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3457f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
34581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3459f85e193739c953358c865005855253af4f68a497John McCall
3460dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3461dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3462dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3463b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3464c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
34651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3466c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
34671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3468c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3469c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
347031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
347131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3472b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3473b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
34741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3475b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
34766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
34771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
34786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3479521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
34801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3481521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
34821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
34831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break;
34841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
34851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3486742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  case AttributeList::AT_arc_weakref_unavailable:
3487742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3488742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
34891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
34901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
34911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
34921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3493026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
34941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
34951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
34961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3497803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
34981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3499803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
35000db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
35011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
35020db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3503d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
35041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3505d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
35061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break;
35071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
35081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
35091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
35101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
35111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
35121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
35131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
35141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3515bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
351605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
351705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
35187255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
35191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
35207255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
352104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
352204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
352304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3524f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
352552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3526414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
35271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
352804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3529f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
35301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3531f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
353211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
35331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
353411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3535fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3536fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3537fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3538fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3539fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3540fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3541fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3542fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3543fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3544fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3545fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3546fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3547fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3548fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3549fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3550fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3551fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3554db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3555db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3556db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3558db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3559db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3560db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3561db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3562db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3563db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3565db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3566db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3568db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3569db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3571db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3572db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3573db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3574db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3575db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3577db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3579db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3580db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3583db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3586db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3587db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3591fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3592803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
359382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
359482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
359582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
35967d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
35977d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3598803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3599803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3600803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3601803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
360260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
360360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
360460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
360560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
36061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
36071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
360860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
360960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
361060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
361160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
361260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
361360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
361460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
361560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
361660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
36171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
361860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
361960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
36201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
362160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
362260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3623803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3624803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3625f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
362660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
362760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
362811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
36291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
363011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
363111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
363211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
363311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
363411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
363560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
363611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3637dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
363811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3639803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3640803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3641803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
3642e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3643e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
3644900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
3645900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
36467b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3647e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3648e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3649900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
3650900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
3651900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
3652900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
3653900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
3654900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3655900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
3656900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
3657900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
3658900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
3659900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
3660900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
3661900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
3662900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3663900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
3664c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3665900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3666900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
3667900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
3668900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
3669900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
3670900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
3671900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
3672900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
3673900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
3674900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
3675900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
3676900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
36774278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
3678b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3679e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3680e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3681ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3682a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
368316573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
368416573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3685b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3686b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3687c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3688b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3689e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3690e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3691e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3692e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3693e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3694e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
36957b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3696c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3697c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3698c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3699c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3700900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
3701cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3702cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3703cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3704c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3705c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3706c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3707c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3708c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3709c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3710c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3711c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3712cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3713e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3714e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3715e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
37160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
37170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
37180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
371960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
372060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3721d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3722d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
372331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
372431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
372531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
372631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
372731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
372831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
372931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
373031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
373131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
373231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
373331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
373431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3735d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3736e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3737e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3738e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3739e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
37400744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
37417f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
374260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3743bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
37440744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
37450744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
37460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
37470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
37480744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
37490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
375060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3751bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
37520744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
37530744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
375460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
37550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
375654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3757f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3758f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3759f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3760f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3761f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3762f85e193739c953358c865005855253af4f68a497John McCall  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl))
3763f85e193739c953358c865005855253af4f68a497John McCall    return false;
3764f85e193739c953358c865005855253af4f68a497John McCall
3765f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3766f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3767f85e193739c953358c865005855253af4f68a497John McCall}
3768f85e193739c953358c865005855253af4f68a497John McCall
3769f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
3770f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3771f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
3772f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
3773f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3774f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
3775f85e193739c953358c865005855253af4f68a497John McCall    return;
3776f85e193739c953358c865005855253af4f68a497John McCall  }
3777f85e193739c953358c865005855253af4f68a497John McCall
3778f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3779f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3780f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
3781f85e193739c953358c865005855253af4f68a497John McCall}
3782f85e193739c953358c865005855253af4f68a497John McCall
3783eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3784eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3785eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3786eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3787eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3788eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3789eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3790eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3791eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3792eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3793eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3794eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3795eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3796eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3797eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3798eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3799eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3800eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3801eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3802eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3803eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
380454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
380554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3806eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3807eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
3808eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
380954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3810eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
3811eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
3812eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
3813eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
381454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3815eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
3816eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
381754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3818eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
3819eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
3820eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
382158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
38222f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
38232f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
3824a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis  if (decl && !decl->isInvalidDecl()) {
3825eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
3826eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
38272f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
38282f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
38292f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
38302f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
38312f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
3832eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3833eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
3834eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
38352f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
38362f514480c448708ec382a684cf5e035d3a827ec8John McCall
3837eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
38382f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
3839eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
38402f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
38412f514480c448708ec382a684cf5e035d3a827ec8John McCall
38422f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
3843eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
38442f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
3845f85e193739c953358c865005855253af4f68a497John McCall
3846f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
3847f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
3848f85e193739c953358c865005855253af4f68a497John McCall        break;
384954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
385054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
385154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
385254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
385358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
3854eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
385529233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
385658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
3857eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
38582f514480c448708ec382a684cf5e035d3a827ec8John McCall}
38592f514480c448708ec382a684cf5e035d3a827ec8John McCall
38602f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
38612f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
38620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
38632f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
38642f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
38652f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
38662f514480c448708ec382a684cf5e035d3a827ec8John McCall}
38672f514480c448708ec382a684cf5e035d3a827ec8John McCall
38689c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
38692f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
38702f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
38712f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
38722f514480c448708ec382a684cf5e035d3a827ec8John McCall
38732f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
3874ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
3875c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
3876ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
3877ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
3878c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
3879c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
3880ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
388154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
388254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
38835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
38848e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
388589ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
388654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
3887eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3888eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
388954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
389054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
389154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
389254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
389354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
389454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
3895ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
3896c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3897c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
38988e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
3899743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
39008e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
390189ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
39028e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
390389ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
390489ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
39058e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
390654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
3907