SemaDeclAttr.cpp revision 3ac1fbc303d22af2e11a14023ecee7bd7b7d0bfd
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.
2773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskibool checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
2783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                            const RecordType *RT) {
2793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // Flag error if could not get record type for this argument.
2803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  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.
2863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  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
307b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (ArgExp->isTypeDependent())
3083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski     continue;
309b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
311b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
314b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
318b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
319b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
320b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
321b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
3223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
3233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
3243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
325b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
326b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
327b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          return false;
328b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
3293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
3303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        RT = getRecordType(ArgTy);
331b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
332b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
333b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (!checkForLockableRecord(S, D, Attr, RT))
335b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return false;
336b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
338b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
339b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return true;
340b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
341b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
342e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
343e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
344e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
345e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
3463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
3473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
3483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
3493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
350fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
351fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
352fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
353fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
354fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
355fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
356fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
357fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
358fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
359fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
360b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
361fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
362fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
363fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
364fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
365fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
366fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
367fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
368fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getLoc(), S.Context));
369fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
370fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getLoc(), S.Context));
371fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
372fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
373db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
374b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
375db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
376db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
377b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
378db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
379db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
3803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
3813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
382db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
383db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
384db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
385b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
387db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
388db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
389db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
3923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
3933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return;
3943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
3963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType())))
397b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
398b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
399db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
4003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getLoc(),
4013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 S.Context, Arg));
402db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
4033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getLoc(), S.Context, Arg));
404db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
405db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
406db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
407fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
408fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
409fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
410fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
411fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
412fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
413fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
414fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
415fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
416fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
418fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
419fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
420fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
421fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getLoc(), S.Context));
422fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
423fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) LockableAttr(Attr.getLoc(), S.Context));
424fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
425fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
427fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
428fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
433b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getLoc(),
440fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
443db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
444db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
445db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
446db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
447b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
448db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
449db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
450db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
451b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
452b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
453db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
454b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
455db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
456db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
457db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
458b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // Check that this attribute only applies to lockable types
459b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
460b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
461b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
462b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
463b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      S.Diag(Attr.getLoc(), diag::err_attribute_decl_not_lockable)
464b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
465b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
466b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
467b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
468b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
470b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
4713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
472b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
473b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
4753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
4763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
4773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
478db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
4793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getLoc(), S.Context,
4803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                    StartArg, Size));
481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
4823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getLoc(), S.Context,
4833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                   StartArg, Size));
484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
485db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
486db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
487b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
488db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
489db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
491db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
492b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
493b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
494db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
495db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
496db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
497db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
498db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
499b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
5013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
502b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
503b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
508db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
509db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getLoc(),
5103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
5113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
512db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getLoc(),
5143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        S.Context, StartArg,
5153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        Size));
516db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
517db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
518db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
519b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
520db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
521db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
522b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
525b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
526b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
527db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
528db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
529db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
530db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
531db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
532b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
533b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
534b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
535b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
536b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
537b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 2> Args;
5393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Args.push_back(Attr.getArg(0)); //FIXME
540b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1))
542b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
543b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
549db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getLoc(),
5503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              S.Context,
5513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              StartArg, Size));
552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getLoc(),
5543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
5553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
556db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
558db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
559b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
560db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
561db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
562b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
563db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
565b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
566db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
568db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
569db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
571b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
5733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
574b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
575b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
580db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getLoc(),
5823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            S.Context, StartArg,
5833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            Size));
584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getLoc(),
5863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         S.Context, StartArg,
5873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         Size));
588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
591b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
592db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
593db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
594db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
595db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
596b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
597db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
598db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
599db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
600db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
601db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
602b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
6043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
605b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
606b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
6113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getLoc(), S.Context,
6123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
613db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
614db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
615db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
616b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
617db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
619b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
620db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
6213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
622db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
623b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
624db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
625db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
626db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
627db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
628db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
630b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
631b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
6333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType())))
6343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return;
6353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
6363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getLoc(), S.Context, Arg));
637db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
638db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
639db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
640b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
641db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
643b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
645db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
646b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
647db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
648db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
650db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
651db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
652b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
6543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
655b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
656b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
6613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getLoc(), S.Context,
6623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
663db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
664db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
6671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
66887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
669545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
670803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
671545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
673bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
6759cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
6779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6789cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
6799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
680f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
681f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
682f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
6834ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
6844ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
6854ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
6864ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
6874ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
6884ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
6899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
6909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
6911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
6929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
6931731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
6947a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
6956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
6989cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
6999ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
7009cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
701ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
702a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
703bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
7059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
7066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
7111731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
713bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
71487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
715cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
71687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
7176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
7196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
720803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
721fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
72208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
7236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
724cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
7256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
7263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
73087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
731c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getLoc(), S.Context));
732c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
733c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
734c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
735c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
7361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
73796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
7381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
73996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
740bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
74163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
74287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
74363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
74487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
74563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
74663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
74763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7484ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
74963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
75063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
75263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
7531731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
75463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
75563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
75663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
757efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
75887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D)) {
75987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
76063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
761efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
76263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7634ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
76496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
76596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
7661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
7671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
768857e918a8a40deb128840308a318bf623d68295fTed Kremenek
769857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
770a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
771857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
772857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
773857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
774857e918a8a40deb128840308a318bf623d68295fTed Kremenek
775857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
776857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
77787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!(isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
7784ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
779857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
780857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
78187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
7823a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
7833a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
7843a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
7853a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
7863a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
78787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7883a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
7893a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
7903a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
7913a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
7923a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
7933a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
794a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
795a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
796a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
7973a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
798b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
79987c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
800a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
801a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
802a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
803a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
804b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
805a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
806a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
807a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
808a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
809a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
810a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
811a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
812a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
813a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
81487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
815cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
816857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
817857e918a8a40deb128840308a318bf623d68295fTed Kremenek
818d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
81968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
82068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
82168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
82268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
82368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
82468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
82568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
82668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
82768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
82868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
82968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
83068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
83168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
83268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
8331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
834bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
835bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
83687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
837fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
838883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
839eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
840eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
841bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
84207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
84307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
84487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
84587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
846eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
847eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
8485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
849bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
850eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
851eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
852bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
853bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
854eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
8557a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
856eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
857ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
858ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
859fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
860fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
861eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
862eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
864eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
865bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
866eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
867fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
86830bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
869eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
870eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
871bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
872465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
87307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
87407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
87507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
87607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
87707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
87807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
87907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
88007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
88107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
882eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
883eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
88487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
885d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
88668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
887dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
888eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
889c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
890fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
8917fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
892eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
893bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
894eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
895eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
896bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
897bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
898bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
8997fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
90087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
90187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
902d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
903dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
904d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
90546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
906bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
907ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
90860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
90960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
91060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
91160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
91260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
9137fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
91460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
915eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
9167fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
9177fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
9187fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
919dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
92087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
921cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
922eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
923eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
9241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
925dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
926dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
927dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
928dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
929dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
930dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
9312a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
9322a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
933dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
934dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
935dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
936dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
937dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
938dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
939dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
940cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
9412a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
9422a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
943cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
944dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
945dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
946dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
947dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9482a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9492a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
950cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
951dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
952dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
953dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
954dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
957cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
959dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
960dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
961dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
962dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9632a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9642a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
9652a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
9662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
967dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
968dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
96987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
970883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
971883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
972dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
973dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
974dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
97507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
97607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
97787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
97887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
979dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
981dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
982dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
983dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9865f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
987dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
9892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
990dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9917a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
992dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
993dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
994dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
995dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
997dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
998dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
999dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1000dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1002dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1004dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
100807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
100907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
101007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
101107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
101207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
101307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
101407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
101507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
101607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1018cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1019cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1020dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
102187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1022dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1023dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1024dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1025cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1026dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1027dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1030dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1031dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1032cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1033dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1034dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
10357a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1036dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1037dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1040dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1041dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1042dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1043dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1044dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1045dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1046dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
10472a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
10482a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
1049dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1052cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
105387c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
105487c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1055cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1056cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1057cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1058cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1059cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1060cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1061cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1062dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1063dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1064dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1065dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1066dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1067dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1068dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1069dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1070dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1072cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1073cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1074cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1075cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1077cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
107887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1079cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1080dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1081dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1082332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1083332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1084332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1085332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1086332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1087332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1088332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1089332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1090332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1091332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1092332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1093332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1094332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1095332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1096332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1097332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1098332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
109911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
110011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
110111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
110311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
110411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
110511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
110611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
110711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
110811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
110987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1110332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1111883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1112332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1113332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1114332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
111587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1116332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
111711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
111811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
111911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
112011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
112111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
112211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
112311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
112411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
112511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
112611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
112787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
11287a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
11297a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1130332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
11317a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
113211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
113311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
113411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
113511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
113611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
113711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
113811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
113911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
114011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
114111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
114211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
114311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
114411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
114511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
114611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
114711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
114811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
114911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
115011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1152332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1153332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
115711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
115811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
115911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
116011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
116111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
11627a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
116411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11665cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
117111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
117387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
1174f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
117787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
117811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
11816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1182545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
11833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1186bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11877a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
11886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
11896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11915cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1192fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
11933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
11946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1197db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar  if (S.Context.Target.getTriple().isOSDarwin()) {
1198f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1199f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1200f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1201f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
12026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
120487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
1205f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
12066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1209dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
12101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1211dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1212dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
121387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1214dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1215883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1216dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1217dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1218dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
121987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
1220dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1221dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
12221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
12231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1224dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1225831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
12263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1227af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1228af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
12295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
123087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
12315bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1232883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
12335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
12345bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1235bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
123687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
1237af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1238af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
12391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1240dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1241831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
124276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
124376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
124476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
12451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
124687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
12482cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
124987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
12502cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
12512cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1252fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1253fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
12542cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
125576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
125676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
12571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
125834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
12591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
126034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
126134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
126287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
126334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
126434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
12651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
126656aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
126787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
126887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
1269722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1270722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1271883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1272a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1273a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
127556aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
127687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
127787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
1278722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1279722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1280883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1281a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1282a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
128487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1285711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1286711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1287711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
128887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1289711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1290883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1291711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1292711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1293711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
129487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
1295711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1296711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1297711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1298831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1299711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1300711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1301711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1302711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1303711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1305b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1306b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
13081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1309b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1310b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1311b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1312b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13131731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
13141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1315b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
131687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
131787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
13183ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
13193ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1320e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1321e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1322b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1323883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1324b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
132519c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
13266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1327b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
132887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
13296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
133135cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
13321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
133335cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
133435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
133535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1336f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1337f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1338f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1339f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1340f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
134135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
134235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
134335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
134435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
134535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
134635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
134735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
134835cc9627340b15232139b3c43fcde5973e7fad30John Thompson
134935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
135035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
135135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
135235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
135335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
135435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
135535cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
135687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
135735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1358883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
135935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
136035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
136135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
136287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
136335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
136435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
136635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
136787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
136801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
136901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
137001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
137101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
137201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
137301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
137401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
137501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
137601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
137701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
137801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
137901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1380f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1381f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
138201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
138301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
138401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
138501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
138601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
138701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
138801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
138987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
139035cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
139135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
13921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
139387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1394bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1395883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1396bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1397bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1398bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1399bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1400bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
14011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
140273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1403831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
140573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
140673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1407bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
140887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
140987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1410fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1411883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
141273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
141373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1414bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
141587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
141673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
141773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
14181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1419b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1420831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1421b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1422b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1423b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1424bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
142587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1426186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1427b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1428b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1429b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
143087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1431b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1432883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1433b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1434b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1435bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
143687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
1437b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1438b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
14391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1441bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1442bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1444bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14487a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1450ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1451ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1452fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
14543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
14553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
14563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
14573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1458bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
145987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1460fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1461883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
14623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
14633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
14643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
146587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
1466f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
14673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
14683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1471bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1472bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1474bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14787a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1480ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1481ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1482fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
14843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
14853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
14863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
14873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1488bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
148987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1490fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1491883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
14923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
14933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
14943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
149587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1496f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
14973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
14983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1500951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1501951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1502bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1503c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1504c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1505951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1506c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
15075f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1508951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1509951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1510c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1511951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1512951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1513c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1514c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1515951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
15166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1517bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
151887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
15196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1522951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1523951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1524bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1525bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1526bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1527951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1528c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
15295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1530951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1531951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1532c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1533951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1534c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1535c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1536c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1537951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1538c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
153987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
1540bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1541bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1542742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1543742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1544742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1545742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1546742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1547742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1548742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1549742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1550742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1551742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                          Attr.getLoc(), S.Context));
1552742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1553742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
15541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
15551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
15560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
15570a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
15580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15595f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
15600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
15610a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
15620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
15630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
15640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15650a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
15660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15680a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
15690a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
15700a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1571b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
15720a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1573c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
15740a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
15750a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
15763b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Deprecated.Version)) {
15770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
15780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
15790a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
15800a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
15810a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15820a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15830a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
15843b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Obsoleted.Version)) {
15850a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
15860a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
15870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
15880a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
15890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
15923b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Deprecated.Version <= Obsoleted.Version)) {
15930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
15940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
15950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
15960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
15970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
159987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
16000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
16010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
16020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1603b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1604b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                IsUnavailable));
16050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
16060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
16091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
16106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1611bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16127a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
16136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
16146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1615bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16165cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1617fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
16183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
16196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1621bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1623cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1624bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1625c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1626cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1627c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1628cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1629c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1630cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1631c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1632cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
16336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
163408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
16356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1637bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
163887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
16396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
16406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
16421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1643d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1644d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
164587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1646883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1647d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1648d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1649d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
165087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
165187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
165287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1653d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1654d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
165587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1656d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
165787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1658d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1659d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1660d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
16615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1662d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1663d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1664d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1665d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1666d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1667d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1668d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1669d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1670d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1671d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1672d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1673d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1674d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1675d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1676d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1677d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
167887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1679d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1680d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1681d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1682f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1683f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1684f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1685f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1686f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1687f85e193739c953358c865005855253af4f68a497John McCall    return;
1688f85e193739c953358c865005855253af4f68a497John McCall  }
1689f85e193739c953358c865005855253af4f68a497John McCall
169087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getLoc(),
1691f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1692d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1693d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
16941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
16951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
16961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
16970db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1698bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16990db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
17000db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
17010db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
17020db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
17030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1704bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1705cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
17060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
17070db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
17081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1709fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
17102b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1711fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1712fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1713162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1714fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1715fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
17166217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1717fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1718fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1719fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1720fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1721cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1722fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1723fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1724bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
17251b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1726f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
17272b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1728f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1729f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1730f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1731f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1732f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1733f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1734f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1735f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1736cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1737f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1738f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
17391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1740bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1741fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
17423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
17439eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
17449eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1745bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17469eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
17473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
17489eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
17499eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1750bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1751cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
175292e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
17539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
17549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1755fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
17563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
17579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
17589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1759bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
176087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
17619eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
17629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
17631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1764770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1765770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1766bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1767770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1768bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1769bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1770770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1771770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
17727a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1773770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1774ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1775ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1776fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
17773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1778770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1779770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1780770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1781bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1782770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1783fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1784fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1785770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1786770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1787770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1788770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1789770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1790770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
17917a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1792770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1793ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1794ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1795fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
17963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1797770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1798770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1799770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1800bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1801770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1802770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1803770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1804fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1805fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1806770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1807770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1808770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1809770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
181087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1811183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1812897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1813bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1814897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1815897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1816897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1817897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1818bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1819897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
18203bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1821770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1822bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
182387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1824770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
18253bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1826770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
18272f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
182887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (isa<BlockDecl>(D)) {
1829bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1830bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
18312f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
183287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
18332f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1834daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
183587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1836f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
18372f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
18383bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
18393bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
18402f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
18412f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1842ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
18432f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1844883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
18452f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
18462f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1847770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1848fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1849883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1850770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1851770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
185287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1853f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1854770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1855770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
18561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1857026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
18581731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1859026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1860026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1861f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1862026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1863883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1864026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1865026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1866bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1867f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1868f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1869f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1870f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1871f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1872f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1873f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1874f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1875f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1876f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1877f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1878f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1879cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1880026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1881026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
18821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
188487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
188587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
18866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18886e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
188987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
189087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
189187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1892f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1893f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1894f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
189587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1896332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1897332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1898332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
189987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
19006e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19016e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1902bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
190387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  nd->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
19046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
19081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
19096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
19116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19126e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
19136e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
19140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
19150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
19160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
19170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
19180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
1919def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1920db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar             (S.Context.Target.getTriple().isOSDarwin() &&
1921def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor              isa<ObjCInterfaceDecl>(D))) {
1922def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
1923def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
1924c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1925883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
19266e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
19296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1930cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
19316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
19326e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
19341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
19356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
19361731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
19376f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
19386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
19396f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
19406f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
19417a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
19426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1943ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1944ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
19456f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
19466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
19476f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
19486f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
19496f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
19506f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1951cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1952cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
19536f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
19546f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
19556f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
19561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
195717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
19581731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
195917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
196017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
196117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
196217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
19637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1964797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
196517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1966797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
196717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
196817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
19691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1970797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1971bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1972a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1973a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1974a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1975797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1976797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
19771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1978a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1979a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1980a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1981a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1982a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1983a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1984f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1985f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
198617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
198717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
19886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1991831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
19923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1995b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
199687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
1997b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
1998b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      Existing->setLocation(Attr.getLoc());
1999b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
200087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
2001b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
20026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2005232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2006831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
20073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2008232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2009232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2010bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
201187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2012b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2013b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor     Existing->setLocation(Attr.getLoc());
2014b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
201587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
2016b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2017232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2018232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
20191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2020232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
20211731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2022232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2023bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
202487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
2025232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2026232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
20271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2028bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2029f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2030f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2031f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2032bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2033f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2034f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2035f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2036f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2037bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
203887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2039bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2040f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2041f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2042f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2043f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2044bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2045f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2046c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2047f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2048f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2049f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2050f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2051f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2052f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2053f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2054f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2055bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2056f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2057f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2058f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2059f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2060f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2061f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2062f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2063f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2064f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2065f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2066f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2067f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2068f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2069f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2070bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
207189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
207289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
207389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
207489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2075b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2076b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2077f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
207889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
207989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
208089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
208189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2082bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
208387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
2084223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
2085f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2086f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2087bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2088bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
20891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20901731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
20915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
20921731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
209387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
20945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2095883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
20965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
20975b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
209807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
209907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
210007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
210187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
210287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
21035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
210407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
21055b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
21067a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
21075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2108ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2109ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
21105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
21115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
21125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2114bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
21165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
21175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
21185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2120bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2122bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
212307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
212407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
212507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
212607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
212707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
212807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
212907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
213007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
213107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
21325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
213387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
21365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
21375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
21385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
21396217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
21405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
21415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2142bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
21435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
21445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2145bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
214687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
21475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
21485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
21495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
21506217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
21515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
21525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
21545b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
21555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2156bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2157bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
215887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
215907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
21605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
21615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
21622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
21632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
21642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
21652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
21662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
21673c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
21682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
21692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
21702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
21712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
21722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
21735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
21742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
21752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
21762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
21772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
21782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
21792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
21802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
21812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
21822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
21832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
21842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
21852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
2186cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2187cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
21882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
21892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2190bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2191bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
21923c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
21933c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
21942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
21952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
21962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2197521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2198521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
21991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
22001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
2201521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
2202521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2203521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2204521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2205521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
220687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2207b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2208b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2209b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2210b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
221187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2212b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2213b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2214b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2215b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2216b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2217b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2218b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2219b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2220521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2221521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2222521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2223521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2224521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
22257a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2226b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2227521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2228521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2229521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2230521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2231521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2232521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2233521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2234521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
22359f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2236521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2237521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2238521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2239521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2240521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2241521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
224287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
2243f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2244521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2245521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2246bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2247bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
22481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
22496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2250545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2251fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
22523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
22536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2256545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
22573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
22586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
226187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2262fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2263883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
226707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
226807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
226987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
227087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
22716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
22726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
22746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
22762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
22772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
22782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
22802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
22813c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22823c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
22833c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
22843c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2286fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
228701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
22886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
22927a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2293803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2294ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2295ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2296fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
22973c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
22986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2302fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
23033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
23086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2309bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23104a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
23114a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
231207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
231307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
231407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
23154a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
23164a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
23174a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
23184a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
23191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
232187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
23226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2324085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2325fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2326fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2327085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2328085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
23292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2330390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2331390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2332803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2333390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2334fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2335fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
23366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2337bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
23386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
23396217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2340390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2341fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2342fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
23436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
23477a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2348803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2349ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2350ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2351fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
23536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
23576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
235887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
23596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
23606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
236187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
23626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
23636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
23646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23663c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
23673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
23682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
23696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2370fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2371fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
23726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
23736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
23746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
23756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2376fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
23773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
23786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2381b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2382b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
238387c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
238487c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2385b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2386b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2387b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2388b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2389b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2390b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2391b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2392b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2393b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->setLocation(Attr.getLoc());
2394b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2395b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2396b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2397b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
239887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
2399cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
24002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
24016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
24041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
24056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
24061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
24076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
24096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
24110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
241287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
24130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
24140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
24150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
241687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
24170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
24180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2419fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2420883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
24216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
2425bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
24260c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
24270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
24290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
243017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
243117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
24320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
24330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
24340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2436bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
24370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
24380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
243990cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2440bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
244190cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
244290cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
24430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2445bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
24460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
24470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
24480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
24490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
24500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
24510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
24520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
24530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2454bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
24550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2456bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
24570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
24580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
24590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2460bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
24610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
24620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2463bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2464bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2465bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
24666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2467cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
24686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
24721731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
24736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24741731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
24757a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2476797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2477bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
24796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
24806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2481797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
24826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
248487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
2485f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
24866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2490545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
24913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
24926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2494bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2495bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2496bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2497bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
24986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2499545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2500cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
25014ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
25024ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
25034ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
25047a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
25054ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
25064ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
25074ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
25084ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
25094ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2510cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
25116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2513bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2514cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
251549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
25164ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
25174ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
25184ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
251949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
252049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2521396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
25224ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
25234ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2524396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2525396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2526396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2527cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2528cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2529cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2530cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
2531cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2532cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2533cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
2534cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
25356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2536fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2537d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2538bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2539fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2540bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2541bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2542bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
25431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2544fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2545fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2546fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2547fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
25481731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2549fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
25501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2551fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2552fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2553fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
25540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2555fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2556fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2557210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
25585f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2559fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2560fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2561210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2562210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2563fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2564fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2565fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
256673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2567210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2568fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
256973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
257073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
257173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
257273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
257373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
257473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
257573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
257673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
257773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
257873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
257973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
258073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
258173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
258273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
258373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
258473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2585fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2586fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2587fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2588fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2589210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
25900b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2591210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
25920b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
2593fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2594fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2595210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
25960b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2597fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2598fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2599fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2600fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2601162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2602fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2603fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2604fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2605fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2606fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2607fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2608fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2609fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
261073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2611183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
261273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
261373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
26142ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
261573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
261673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
261773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
261873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
261973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
262073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
262173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
262273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
262373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2624390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2625390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2626390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2627390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2628f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2629f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2630fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2631fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2632fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
26333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2634fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2635fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
26363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2637fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2638fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
263973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
264073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
264173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
264273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2643fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
26440b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2645fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
26460b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2647fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2648fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
264973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
265073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
265173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
265273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2653fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
26540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2655fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
26560b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2657fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2658fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2659fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
26600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2661fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
26620b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2663fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
26640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2665fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2666fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2667fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
26680b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2669fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2670aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2671aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2672aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2673aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2675aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2676aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2677aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2678aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2679fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
268073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
268173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
268273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2683f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2684f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2685f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2686f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2687f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2688f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2689f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2690f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2691f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
269273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2693fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2694fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
269573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
269673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2700162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2701ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2702a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2703ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2704fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2705fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
27060744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
27071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2708d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
27091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2710d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2711e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
271287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2713d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2714883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2715d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2716d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2717bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
271887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2719d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2720d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
27211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
27225bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
27231731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
27245bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
27251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2726bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
272787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
27285bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2729883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
27305bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
27315bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
273387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
27345bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
27355bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
27361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
27371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
27387255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
27391731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
27407255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
27411731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
27427255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
274387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
27447255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2745883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
27467255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
27477255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
27487255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
274987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2750f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
27517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
27527255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
27531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2754ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2755ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2756831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2757ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2758ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2759ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2760ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
276187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2762ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2763883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2764ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2765ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2766ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
276787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2768ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2769ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2770ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2771ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2772ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
27731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2774ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2775ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2776ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2777ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2778ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2779ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2780ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
278187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2782ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2783883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2784ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2785ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2786ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
278787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2788ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2789ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2790ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2791ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2792ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
27931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2794ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2795ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
27961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2797ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2798ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
279987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2800ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2801883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2802ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2803ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2804ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
280587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
28062c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2807723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
28082c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
28092c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
28102c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
28112c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
28122c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
28132c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
28142c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
28152c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
28162c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
28172c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
28182c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
28192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
282087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2821ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2822ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2823ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2824ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2825ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2827ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2828ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28291731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2830ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
28311731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2832ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
283387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2834ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2835883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2836ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2837ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2838ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
283987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2840ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2841ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2842ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2843ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2844ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2846ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2847ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28481731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2849ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
28501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2851ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
285287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2853ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2854883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2855ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2856ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2857ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
285887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2859ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2860ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2861ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2862ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2863ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
286526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
28661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
286726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2868bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
286987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2870c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
287126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2872883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
287326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
287426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2875bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
28760130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2877cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2878c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2879c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2880bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
288187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
288226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
288326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
28841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
288587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2886711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
288787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2888e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2889711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
289087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
2891711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2892e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
289387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
289487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
289587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2896711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2897711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2898711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
289987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2900e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
290187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2902e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2903e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
290487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2905e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2906f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
290787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
290804633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2909e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
291087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2911e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
291252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
291387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
291452fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2915414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
291687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
2917414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
29185cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
291987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2920414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
292187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2922414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2923414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2924414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
29255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2926414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2927414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2928414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2929414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2930414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2931414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
293287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
293387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2934414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2935414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2936414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
293787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PcsAttr(Attr.getLoc(), S.Context, PCS));
2938414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2939e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2940e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2941e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2942e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2943e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2944e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
29451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
294656aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
294787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2948f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2949f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2950711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2951711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2952711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2953711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2954831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
2955831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2956831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
2957711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2958711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2959711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2960ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
296155d3aaf9a537888734762170823daf750ea9036dEli Friedman
2962414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
2963414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
2964711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2965711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
2966711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2967711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2968711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2969711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2970414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2971414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2972414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
29735cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
2974414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2975414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2976414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2977414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
2978414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2979414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
29805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2981414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
2982414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
2983414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2984414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
2985414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
2986414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2987414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2988414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
2989414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2990711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
2991711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2992711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2993711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2994711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2995711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
29961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
299787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2998711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2999711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
300087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3001711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3002711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
300387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
300487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
300587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3006ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3007ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
300855d3aaf9a537888734762170823daf750ea9036dEli Friedman
300987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, numParams));
3010711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3011711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3012711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3013711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
301487c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
301587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3016711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3017711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
301887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
301987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
302087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3021711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3022711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3023711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
302487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
302555d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3026ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3027711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
302887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
302955d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
303087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3031711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
303255d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
303355d3aaf9a537888734762170823daf750ea9036dEli Friedman
3034711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (Context.Target.getRegParmMax() == 0) {
303587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
303655d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
303787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3038711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
303955d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
304055d3aaf9a537888734762170823daf750ea9036dEli Friedman
3041711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3042711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (numParams > Context.Target.getRegParmMax()) {
304387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3044711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
304587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3046711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
304755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
304855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3049711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3050ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3051ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
30521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
30537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
30547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
30557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3056bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3057bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
30587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
30597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
306187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
30627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3063883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
30647b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
30657b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30667b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
30677b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
30687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
30697b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
30707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
30717b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
30727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
30737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
30747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
30757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30767b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
30777b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
30787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
30797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
30807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
30817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
30827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
30837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
30847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
30857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
30867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
30877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
308987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
30907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
30917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
30927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
30937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
30947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
30957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
30967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
30970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3098b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3099b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3100b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3101c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
3102c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
3103c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3104c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
3105c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
3106c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3107c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
31081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
310987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3110c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
311187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
311287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedParameter;
3113c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3114c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3115c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3116c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
311787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3118c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3119c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3120c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3121c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3122c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3123c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3124c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3125c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
312687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
312787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << cf;
3128c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3129c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3130c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3131c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
313287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getLoc(), S.Context));
3133c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
313487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getLoc(), S.Context));
3135c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3136c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
31371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
31381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
313987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
314087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
314187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedMethod;
3142c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3143c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3144c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
314587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getLoc(), S.Context));
3146c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3147c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
31481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
31491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3150b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3151c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3152bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
315387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3154c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
315587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3156831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
315787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
315887c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3159f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
316087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3161c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
31625dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
316387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
316487c44604325578b8de07d768391c1c9432404f5aChandler Carruth        << SourceRange(Attr.getLoc()) << Attr.getName()
3165883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3166b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3167b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3168bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3169c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3170c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
317187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3172c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
3173c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3174c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3175c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3176c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3177c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3178c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3179c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3180c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3181c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3182c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3183c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3184c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3185c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3186c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3187c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
318887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
318987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc())
319087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3191bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
31925dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3193bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
319487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3195b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3196b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
3197b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3198c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
319987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getLoc(),
3200c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3201c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
320231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
320387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(),
3204f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
320531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
320631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
320787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(),
3208f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
320931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3210b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
321187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(),
3212f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3213b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3214b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
321587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(),
3216f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3217b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3218b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3219b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3220b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3221dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3222dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3223dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3224dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3225dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3226dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3227dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!isa<ObjCMethodDecl>(method)) {
3228dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type)
3229dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc, loc) << attr.getName() << 13 /* methods */;
3230dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3231dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3232dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3233dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3234dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3235dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!resultType->isPointerType() || resultType->isObjCRetainableType()) {
3236dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3237dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3238dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3239dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3240dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3241dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3242dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3243dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3244dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3245dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    ::new (S.Context) ObjCReturnsInnerPointerAttr(loc, S.Context));
3246dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3247dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
32481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
32491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
325087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3251f85e193739c953358c865005855253af4f68a497John McCall
325287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  SourceLocation L = Attr.getLoc();
325387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
325487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
3255f85e193739c953358c865005855253af4f68a497John McCall}
3256f85e193739c953358c865005855253af4f68a497John McCall
32571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
32581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
325987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
326087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    SourceLocation L = Attr.getLoc();
326187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
326287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
3263f85e193739c953358c865005855253af4f68a497John McCall    return;
3264f85e193739c953358c865005855253af4f68a497John McCall  }
3265f85e193739c953358c865005855253af4f68a497John McCall
326687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3267f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3268f85e193739c953358c865005855253af4f68a497John McCall
3269f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3270f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
327187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3272f85e193739c953358c865005855253af4f68a497John McCall      << type;
3273f85e193739c953358c865005855253af4f68a497John McCall    return;
3274f85e193739c953358c865005855253af4f68a497John McCall  }
3275f85e193739c953358c865005855253af4f68a497John McCall
3276f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3277f85e193739c953358c865005855253af4f68a497John McCall
3278f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3279f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3280f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3281f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3282f85e193739c953358c865005855253af4f68a497John McCall
3283f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3284f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3285f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3286f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3287f85e193739c953358c865005855253af4f68a497John McCall    break;
3288f85e193739c953358c865005855253af4f68a497John McCall
3289f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3290f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3291f85e193739c953358c865005855253af4f68a497John McCall    break;
3292f85e193739c953358c865005855253af4f68a497John McCall
3293f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3294f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
329587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3296f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3297f85e193739c953358c865005855253af4f68a497John McCall    break;
3298f85e193739c953358c865005855253af4f68a497John McCall  }
3299f85e193739c953358c865005855253af4f68a497John McCall
330087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
330187c44604325578b8de07d768391c1c9432404f5aChandler Carruth                 ObjCPreciseLifetimeAttr(Attr.getLoc(), S.Context));
3302f85e193739c953358c865005855253af4f68a497John McCall}
3303f85e193739c953358c865005855253af4f68a497John McCall
3304f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
3305f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
330611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
330711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
330811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
330911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
331011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
331111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
331211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
331311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
33141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
331511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
331611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
33171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
331811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
33191731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
332011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
332111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
33225cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3323d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3324d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3325d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3326d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3327d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
33285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3329d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3330d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3331d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3332d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3333d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3334d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3335d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3336d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3337d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3338d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3339d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3340d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3341d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3342d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3343d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3344d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
33455f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3346f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3347f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3348f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3349f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3350d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3351d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3352d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3353d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3354d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3355d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3356d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3357d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3358d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3359d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3360d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
336111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
336287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
336311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3364d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
336511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3366f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3367f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3368b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
33690744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
33700744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
33710744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
33721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
33731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
337460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
33751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
33761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
33771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
337860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
337960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
338060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
338160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3382e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
33831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
33841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3385803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
33861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break;
33871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
3388857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
33891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3390803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3391207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3392ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
33936e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
33944211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
33954211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3396bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3397bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3398803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
339960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
340060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
340160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
340260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
340360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
340460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
34051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
34061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3407bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
34081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3409b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
34101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
34111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
34121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3413bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
34141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
34151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
34161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
34171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
34181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
34191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
34203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
34211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
34223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
34231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
34241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
34251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
34261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
34277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
34281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
34297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
34301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
34311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
34321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
34331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
34341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3435dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3436dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3437dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
34381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
34391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
34401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
34411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
34421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
34431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3444b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3445b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
34461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3447f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
34481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3449f85e193739c953358c865005855253af4f68a497John McCall
3450dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3451dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3452dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3453b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3454c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
34551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3456c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
34571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3458c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3459c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
346031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
346131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3462b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3463b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
34641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3465b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
34666f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
34671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
34686f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3469521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
34701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3471521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
34721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
34731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break;
34741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
34751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3476742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  case AttributeList::AT_arc_weakref_unavailable:
3477742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3478742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
34791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
34801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
34811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
34821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3483026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
34841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
34851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
34861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3487803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
34881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3489803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
34900db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
34911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
34920db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3493d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
34941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3495d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
34961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break;
34971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
34981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
34991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
35001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
35011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
35021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
35031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
35041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3505bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
350605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
350705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
35087255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
35091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
35107255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
351104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
351204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
351304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3514f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
351552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3516414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
35171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
351804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3519f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
35201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3521f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
352211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
35231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
352411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3525fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3526fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3527fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3528fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3529fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3530fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3531fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3532fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3533fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3534fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3535fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3536fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3537fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3538fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3539fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3540fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3541fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3542db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3543db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3544db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3545db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3546db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3547db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3549db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3550db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3551db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3554db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3555db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3556db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3558db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3559db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3560db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3561db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3562db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3563db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3565db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3566db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3568db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3569db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3571db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3572db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3573db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3574db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3575db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3577db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3579db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3580db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3581fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3582803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
358382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
358482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
358582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
35867d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
35877d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3588803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3589803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3590803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3591803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
359260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
359360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
359460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
359560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
35961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
35971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
359860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
359960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
360060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
360160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
360260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
360360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
360460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
360560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
360660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
36071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
360860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
360960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
36101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
361160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
361260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3613803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3614803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3615f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
361660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
361760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
361811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
36191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
362011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
362111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
362211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
362311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
362411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
362560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
362611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3627dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
362811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3629803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3630803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3631803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
3632e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3633e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
36341eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
36357b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3636e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3637e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3638e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3639ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                FD->getInnerLocStart(),
3640e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
3641a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
3642b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
3643b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
3644c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3645b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3646e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3647e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3648ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3649a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
365016573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
365116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3652b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3653b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3654c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3655b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3656e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3657e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3658e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3659e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3660e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3661e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
36627b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3663c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3664c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3665c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3666c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3667c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
3668cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3669cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3670cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3671c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3672c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3673c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3674c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3675c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3676c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3677c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3678c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3679cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3680e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3681e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3682e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
36830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
36840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
36850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
368660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
368760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3688d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3689d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
369031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
369131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
369231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
369331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
369431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
369531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
369631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
369731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
369831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
369931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
370031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
370131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3702d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3703e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3704e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3705e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3706e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
37070744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
37087f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
370960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3710bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
37110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
37120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
37130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
37140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
37150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
37160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
371760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3718bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
37190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
37200744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
372160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
37220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
372354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3724f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3725f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3726f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3727f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3728f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3729f85e193739c953358c865005855253af4f68a497John McCall  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl))
3730f85e193739c953358c865005855253af4f68a497John McCall    return false;
3731f85e193739c953358c865005855253af4f68a497John McCall
3732f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3733f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3734f85e193739c953358c865005855253af4f68a497John McCall}
3735f85e193739c953358c865005855253af4f68a497John McCall
3736f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
3737f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3738f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
3739f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
3740f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3741f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
3742f85e193739c953358c865005855253af4f68a497John McCall    return;
3743f85e193739c953358c865005855253af4f68a497John McCall  }
3744f85e193739c953358c865005855253af4f68a497John McCall
3745f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3746f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3747f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
3748f85e193739c953358c865005855253af4f68a497John McCall}
3749f85e193739c953358c865005855253af4f68a497John McCall
3750eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3751eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3752eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3753eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3754eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3755eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3756eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3757eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3758eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3759eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3760eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3761eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3762eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3763eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3764eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3765eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3766eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3767eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3768eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3769eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3770eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
377154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
377254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3773eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3774eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
3775eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
377654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3777eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
3778eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
3779eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
3780eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
378154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3782eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
3783eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
378454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3785eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
3786eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
3787eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
378858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
37892f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
37902f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
3791a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis  if (decl && !decl->isInvalidDecl()) {
3792eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
3793eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
37942f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
37952f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
37962f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
37972f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
37982f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
3799eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3800eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
3801eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
38022f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
38032f514480c448708ec382a684cf5e035d3a827ec8John McCall
3804eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
38052f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
3806eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
38072f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
38082f514480c448708ec382a684cf5e035d3a827ec8John McCall
38092f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
3810eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
38112f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
3812f85e193739c953358c865005855253af4f68a497John McCall
3813f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
3814f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
3815f85e193739c953358c865005855253af4f68a497John McCall        break;
381654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
381754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
381854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
381954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
382058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
3821eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
382229233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
382358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
3824eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
38252f514480c448708ec382a684cf5e035d3a827ec8John McCall}
38262f514480c448708ec382a684cf5e035d3a827ec8John McCall
38272f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
38282f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
38290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
38302f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
38312f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
38322f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
38332f514480c448708ec382a684cf5e035d3a827ec8John McCall}
38342f514480c448708ec382a684cf5e035d3a827ec8John McCall
38359c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
38362f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
38372f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
38382f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
38392f514480c448708ec382a684cf5e035d3a827ec8John McCall
38402f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
3841ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
3842c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
3843ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
3844ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
3845c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
3846c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
3847ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
384854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
384954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
38505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
38518e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
385289ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
385354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
3854eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3855eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
385654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
385754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
385854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
385954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
386054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
386154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
3862ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
3863c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3864c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
38658e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
3866743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
38678e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
386889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
38698e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
387089ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
387189ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
38728e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
387354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
3874