SemaDeclAttr.cpp revision c90df6a0ad61041e976e0136c29e6d57b17cba3d
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.
264b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskiconst RecordType *getRecordType(QualType QT) {
265b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = QT->getAs<RecordType>();
266b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    // now check if we point to record type
267b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if(!RT && QT->isPointerType()){
268b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        QualType PT = QT->getAs<PointerType>()->getPointeeType();
269b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        RT = PT->getAs<RecordType>();
270b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
271b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return RT;
272b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
273b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
274b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
275b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// from Sidx, resolve to a lockable object. May flag an error.
276b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttrArgsAreLockableObjs(Sema & S, Decl *D,
277b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         const AttributeList & Attr,
278b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
279b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
280b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  for(unsigned int Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
281b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
282b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (ArgExp->isTypeDependent())
283b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      continue;
284b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
285b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    QualType Arg_QT = ArgExp->getType();
286b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
287b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    // Get record type.
288b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    // first see if we can just cast to record type, or point to record type
289b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(Arg_QT);
290b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
291b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    // now check if we idx into a record type function param
292b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT && ParamIdxOk) {
293b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      FunctionDecl *FD = dyn_cast <FunctionDecl>(D);
294b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
295b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
296b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
297b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
298b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        uint64_t ParamIdx_from1 = ArgValue.getZExtValue();
299b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        uint64_t ParamIdx_from0 = ParamIdx_from1 - 1;
300b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdx_from1 > NumParams) {
301b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
302b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
303b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          return false;
304b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
305b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        Arg_QT = FD->getParamDecl(ParamIdx_from0)->getType();
306b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        RT = getRecordType(Arg_QT);
307b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
308b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
309b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
310b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    //  Flag error if could not get record type for this argument
311b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT) {
312b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_class)
313b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
314b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return false;
315b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
316b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
317b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    // Flag error if the type is not lockable
318b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT->getDecl()->getAttr<LockableAttr>()) {
319b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_lockable)
320b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
321b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return false;
322b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
323b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
324b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return true;
325b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
326b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
327e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
328e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
329e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
330e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
3313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
3323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
3333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
3343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
335fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
336fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
337fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
338fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
339fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
340fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
341fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
342fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
343fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
344fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
345b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
346fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
347fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
348fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
349fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
350fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
351fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
352fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
353fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getLoc(), S.Context));
354fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
355fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getLoc(), S.Context));
356fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
357fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
358db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
359b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
360db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
361db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
362b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
363db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
364db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
365db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
366db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
367db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
368b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
369db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
370db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
371db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
372db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
373db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
374db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
375b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
376b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr))
377b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
378b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
379db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
380db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getLoc(), S.Context));
381db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
382db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getLoc(), S.Context));
383db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
384db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
385db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
386fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
387fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
388fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
389fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
390fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
391fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
392fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
393fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
394fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
395fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
396fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
397fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
398fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
399fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
400fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getLoc(), S.Context));
401fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
402fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) LockableAttr(Attr.getLoc(), S.Context));
403fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
404fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
405fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
406fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
407fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
408fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
409fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
410fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
411fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
412b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
413fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
414fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
415fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
416fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
418fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getLoc(),
419fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
420fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
421fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
422db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
423db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
424db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
425db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
426b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
427db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
428db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
429db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
430b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
431b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
432db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
433b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
434db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
435db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
436db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
437b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // Check that this attribute only applies to lockable types
438b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
439b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
440b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
441b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
442b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      S.Diag(Attr.getLoc(), diag::err_attribute_decl_not_lockable)
443b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
444b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
445b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
446b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
447b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
448b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
449b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr))
450b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
451b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
452db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
453db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getLoc(), S.Context));
454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
455db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getLoc(), S.Context));
456db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
457db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
458db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
459b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
460db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
462db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
463db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
464b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
465b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
466db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
467db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
468db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
469db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
470db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
471b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
472b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, 0, /*ParamIdxOk=*/true))
473b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
474b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
475db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
476db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getLoc(),
477db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                                           S.Context));
478db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
479db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getLoc(),
480db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                                        S.Context));
481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
482db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
483db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
484b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
485db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
486db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
487b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
488db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
489db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
490b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
491b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
492db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
493db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
494db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
495db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
496db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
497b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
498b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
499b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
500b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
501b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
502b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
503b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
504b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, 1))
505b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
506b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
507db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
508db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getLoc(),
509b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                                              S.Context));
510db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
511db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getLoc(),
512b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                                           S.Context));
513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
514db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
515db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
516b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
517db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
518db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
519b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
520db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
521db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
522b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
525db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
526db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
527db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
528b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
529b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr))
530b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
531b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
532db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
533db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getLoc(),
534b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                                            S.Context));
535db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getLoc(),
537b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                                         S.Context));
538db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
539db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
540db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
541b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
542db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
543db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
544db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
545db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
546b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
547db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
549db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
550db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
551db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
552b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
553b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, 0, /*ParamIdxOk=*/true))
554b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
555b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
556db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getLoc(), S.Context));
557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
558db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
559db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
560b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
561db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
562db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
563b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
565db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
566b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
568db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
569db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
571db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
572b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
573b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr))
574b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
575b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getLoc(), S.Context));
577db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
579db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
580b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
583b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
586b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
587db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
591db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
592b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
593b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr))
594b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
595b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
596db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getLoc(), S.Context));
597db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
598db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
599db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
6011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
60287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
603545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
604803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
605545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
607bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
6099cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6109cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
6119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6129cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
6139cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
614f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
615f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
616f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
6174ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
6184ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
6194ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
6204ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
6214ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
6224ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
6239cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
6249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
6251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
6269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
6271731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
6287a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
6296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6309cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6319cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
6329cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
6339ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
6349cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
635ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
636a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
637bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6389cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
6399cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
6406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
6446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
6451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
6466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
647bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
64887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
649cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
65087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
6516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
6526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
6536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
654803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
655fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
65608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
6576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
658cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
6596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
6603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
6616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
66487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
665c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getLoc(), S.Context));
666c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
667c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
668c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
669c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
6701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
67196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
6721731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
67396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
674bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
67563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
67687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
67763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
67887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
67963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
68063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
68163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
6824ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
68363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
68463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
6851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
68663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
6871731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
68863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
68963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
69063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
691efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
69287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D)) {
69387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
69463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
695efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
69663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
6974ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
69896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
69996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
7001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
7011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
702857e918a8a40deb128840308a318bf623d68295fTed Kremenek
703857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
704a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
705857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
706857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
707857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
708857e918a8a40deb128840308a318bf623d68295fTed Kremenek
709857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
710857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
71187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!(isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
7124ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
713857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
714857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
71587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
7163a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
7173a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
7183a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
7193a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
7203a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
72187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7223a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
7233a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
7243a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
7253a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
7263a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
7273a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
728a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
729a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
730a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
7313a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
732b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
73387c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
734a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
735a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
736a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
737a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
738b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
739a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
740a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
741a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
742a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
743a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
744a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
745a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
746a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
747a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
74887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
749cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
750857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
751857e918a8a40deb128840308a318bf623d68295fTed Kremenek
752d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
75368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
75468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
75568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
75668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
75768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
75868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
75968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
76068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
76168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
76268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
76368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
76468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
76568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
76668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
7671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
768bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
769bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
77087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
771fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
772883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
773eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
774eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
775bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
77607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
77707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
77887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
77987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
780eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
781eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
7825f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
783bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
784eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
785eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
786bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
787bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
788eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
7897a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
790eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
791ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
792ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
793fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
794fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
795eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
796eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
797bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
798eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
799bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
800eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
801fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
80230bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
803eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
804eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
805bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
806465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
80707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
80807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
80907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
81007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
81107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
81207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
81307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
81407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
81507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
816eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
817eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
81887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
819d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
82068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
821dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
822eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
823c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
824fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
8257fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
826eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
827bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
828eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
829eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
830bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
831bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
832bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
8337fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
83487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
83587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
836d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
837dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
838d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
83946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
840bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
841ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
84260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
84360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
84460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
84560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
84660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
8477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
84860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
849eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
8507fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
8517fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
8527fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
853dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
85487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
855cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
856eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
857eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
8581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
859dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
860dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
861dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
862dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
863dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
864dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
8652a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
8662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
867dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
868dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
869dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
870dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
871dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
872dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
873dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
874cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
8752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
8762a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
877cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
878dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
879dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
880dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
881dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
8822a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
8832a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
884cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
885dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
886dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
887dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
888dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
8892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
8902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
891cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
892dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
893dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
894dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
895dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
896dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
8972a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
8982a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
8992a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
9002a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
901dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
902dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
90387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
904883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
905883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
906dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
907dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
908dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
90907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
91007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
91187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
91287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
913dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
915dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
916dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
917dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
918dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
919dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9205f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
921dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9222a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
9232a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
924dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9257a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
926dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
927dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
928dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
929dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
930dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
931dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
932dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
933dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
934dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
935dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
936dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
937dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
938dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
939dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
940dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
941dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
94207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
94307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
94407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
94507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
94607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
94707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
94807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
94907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
95007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
951dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
952cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
953cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
954dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
95587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
956dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
959cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
960dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
961dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
962dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
963dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
964dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
965dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
966cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
967dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
968dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
9697a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
970dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
971dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
972dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
973dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
974dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
975dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
976dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
977dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
978dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
979dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
980dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9812a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
9822a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
983dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
986cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
98787c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
98887c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
989cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
990cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
991cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
992cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
993cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
994cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
995cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
997dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
998dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
999dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1000dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1002dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1004dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1006cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1007cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1008cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1009cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1010dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1011cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
101287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1013cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1014dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1015dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1016332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1017332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1018332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1019332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1020332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1021332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1022332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1023332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1024332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1025332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1026332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1027332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1028332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1029332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1030332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1031332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1032332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
103311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
103411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
103511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
10361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
103711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
103811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
103911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
104011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
104111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
104211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
104387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1044332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1045883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1046332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1047332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1048332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
104987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1050332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
105111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
105211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
105311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
105411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
105511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
105611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
105711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
105811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
105911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
106011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
106187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
10627a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
10637a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1064332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
10657a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
106611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
106711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
106811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
106911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
107011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
107111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
107211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
107311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
107411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
107511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
107611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
107711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
107811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
107911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
108011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
108111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
108211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
108311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
108411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
108511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1086332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1087332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
108811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
108911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
109011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
109111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
109211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
109311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
109411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
109511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
10967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
109711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
109811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
109911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11005cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
110111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
110211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
110311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
110411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
110511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
110611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
110787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
1108f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
110911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
111011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
111187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
111211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
111311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
11156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1116545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
11173c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1120bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11217a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
11226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
11236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1124bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11255cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1126fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
11273c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
11286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1130bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1131db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar  if (S.Context.Target.getTriple().isOSDarwin()) {
1132f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1133f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1134f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1135f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
11366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1137bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
113887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
1139f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
11406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1143dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
11441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1145dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1146dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
114787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1148dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1149883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1150dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1151dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1152dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
115387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
1154dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1155dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
11561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
11571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1158dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1159831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
11603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1161af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1162af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
11635bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
116487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
11655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1166883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
11675bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
11685bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1169bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
117087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
1171af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1172af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
11731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1174dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1175831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
117676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
117776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
117876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
11791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
118087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
11811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
11822cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
118387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
11842cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
11852cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1186fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1187fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
11882cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
118976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
119076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
11911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
119234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
11931731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
119434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
119534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
119687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
119734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
119834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
11991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
120056aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
120187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
120287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
1203722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1204722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1205883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1206a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1207a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
120956aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
121087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
121187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
1212722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1213722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1214883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1215a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1216a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
121887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1219711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1220711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1221711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
122287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1223711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1224883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1225711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1226711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1227711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
122887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
1229711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1230711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1231711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1232831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1233711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1234711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1235711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1236711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1237711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1238711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1239b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1240b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
12411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
12421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1243b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1244b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1245b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1246b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
12471731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
12481731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1249b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
125087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
125187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
12523ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
12533ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1254e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1255e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1256b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1257883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1258b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
125919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
12606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1261b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
126287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
12636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
126535cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
12661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
126735cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
126835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
126935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1270f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1271f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1272f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1273f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1274f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
127535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
127635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
127735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
127835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
127935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
128035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
128135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
128235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
128335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
128435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
128535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
128635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
128735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
128835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
128935cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
129087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
129135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1292883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
129335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
129435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
129535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
129687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
129735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
129835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
129935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
130035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
130187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
130201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
130301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
130401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
130501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
130601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
130701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
130801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
130901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
131001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
131101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
131201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
131301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1314f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1315f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
131601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
131701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
131801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
131901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
132001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
132101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
132201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
132387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
132435cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
132535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
13261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
132787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1328bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1329883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1330bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1331bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1332bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1333bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1334bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
13351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
133673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1337831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
13383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
133973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
134073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1341bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
134287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
134387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1344fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1345883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
134673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
134773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1348bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
134987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
135073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
135173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
13521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1353b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1354831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1355b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1356b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1357b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1358bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
135987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1360186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1361b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1362b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1363b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
136487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1365b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1366883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1367b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1368b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1369bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
137087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
1371b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1372b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
13731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
13743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1375bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1376bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
13773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1378bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
13793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
13803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
13813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
13827a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
13833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1384ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1385ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1386fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
13883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
13893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
13903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
13913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1392bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
139387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1394fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1395883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
13963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
13973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
13983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
139987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
1400f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
14013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
14023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1405bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1406bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1408bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14127a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1414ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1415ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1416fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14173c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
14183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
14193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
14203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
14213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1422bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
142387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1424fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1425883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
14263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
14273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
14283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
142987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1430f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
14313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
14323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1434951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1435951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1436bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1437c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1438c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1439951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1440c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
14415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1442951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1443951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1444c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1445951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1446951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1447c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1448c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1449951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
14506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1451bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
145287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
14536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1456951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1457951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1458bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1459bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1460bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1461951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1462c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
14635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1464951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1465951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1466c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1467951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1468c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1469c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1470c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1471951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1472c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
147387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
1474bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1475bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1476742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1477742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1478742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1479742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1480742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1481742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1482742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1483742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1484742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1485742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                          Attr.getLoc(), S.Context));
1486742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1487742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
14881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
14891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
14900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
14910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
14920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
14935f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
14940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
14950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
14960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
14970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
14980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
14990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
15000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
15030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
15040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1505b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
15060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1507c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
15080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
15090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
15103b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Deprecated.Version)) {
15110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
15120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
15130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
15140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
15150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
15183b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Obsoleted.Version)) {
15190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
15200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
15210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
15220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
15230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
15263b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Deprecated.Version <= Obsoleted.Version)) {
15270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
15280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
15290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
15300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
15310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
153387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
15340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
15350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
15360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1537b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1538b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                IsUnavailable));
15390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
15400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
15431731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
15446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1545bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15467a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
15476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
15486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1549bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15505cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1551fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
15523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
15536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1555bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1557cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1558bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1559c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1560cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1561c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1562cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1563c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1564cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1565c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1566cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
15676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
156808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
15696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1571bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
157287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
15736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
15761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1577d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1578d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
157987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1580883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1581d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1582d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1583d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
158487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
158587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
158687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1587d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1588d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
158987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1590d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
159187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1592d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1593d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1594d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
15955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1596d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1597d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1598d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1599d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1600d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1601d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1602d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1603d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1604d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1605d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1606d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1607d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1608d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1609d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1610d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1611d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
161287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1613d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1614d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1615d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1616f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1617f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1618f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1619f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1620f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1621f85e193739c953358c865005855253af4f68a497John McCall    return;
1622f85e193739c953358c865005855253af4f68a497John McCall  }
1623f85e193739c953358c865005855253af4f68a497John McCall
162487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getLoc(),
1625f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1626d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1627d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
16281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
16291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
16301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
16310db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1632bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16330db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
16340db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
16350db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
16360db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
16370db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1638bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1639cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
16400db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
16410db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
16421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1643fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
16442b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1645fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1646fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1647162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1648fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1649fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
16506217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1651fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1652fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1653fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1654fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1655cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1656fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1657fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1658bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
16591b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1660f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
16612b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1662f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1663f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1664f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1665f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1666f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1667f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1668f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1669f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1670cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1671f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1672f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
16731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1674bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1675fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
16763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
16779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
16789eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1679bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
16813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
16829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
16839eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1684bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1685cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
168692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
16879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
16889eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1689fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
16903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
16919eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
16929eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1693bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
169487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
16959eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
16969eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
16971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1698770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1699770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1700bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1701770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1702bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1703bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1704770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1705770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
17067a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1707770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1708ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1709ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1710fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
17113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1712770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1713770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1714770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1715bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1716770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1717fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1718fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1719770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1720770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1721770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1722770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1723770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1724770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
17257a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1726770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1727ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1728ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1729fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
17303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1731770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1732770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1733770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1734bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1735770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1736770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1737770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1738fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1739fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1740770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1741770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1742770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1743770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
174487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1745183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1746897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1747bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1748897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1749897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1750897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1751897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1752bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1753897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
17543bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1755770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1756bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
175787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1758770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
17593bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1760770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
17612f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
176287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (isa<BlockDecl>(D)) {
1763bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1764bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
17652f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
176687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
17672f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1768daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
176987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1770f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
17712f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
17723bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
17733bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
17742f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
17752f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1776ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
17772f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1778883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
17792f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
17802f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1781770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1782fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1783883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1784770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1785770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
178687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1787f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1788770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1789770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
17901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1791026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
17921731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1793026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1794026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1795f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1796026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1797883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1798026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1799026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1800bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1801f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1802f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1803f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1804f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1805f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1806f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1807f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1808f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1809f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1810f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1811f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1812f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1813cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1814026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1815026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
18161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
181887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
181987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
18206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
182387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
182487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
182587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1826f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1827f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1828f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
182987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1830332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1831332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1832332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
183387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
18346e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
18356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1836bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
183787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  nd->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
18386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
18396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18416e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
18421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
18436e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
18441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
18456e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
18466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
18476e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
18480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
18490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
18500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
18510a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
18520a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
1853def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1854db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar             (S.Context.Target.getTriple().isOSDarwin() &&
1855def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor              isa<ObjCInterfaceDecl>(D))) {
1856def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
1857def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
1858c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1859883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
18606e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
18616e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
18626e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
18636e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1864cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
18656e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
18666e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
18671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
18681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
18696f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
18701731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
18716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
18726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
18736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
18746f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
18757a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
18766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1877ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1878ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
18796f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
18806f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
18816f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
18826f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
18836f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
18846f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1885cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1886cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
18876f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
18886f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
18896f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
18901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
189117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
18921731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
189317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
189417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
189517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
189617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
18977a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1898797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
189917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1900797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
190117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
190217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
19031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1904797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1905bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1906a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1907a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1908a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1909797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1910797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
19111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1912a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1913a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1914a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1915a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1916a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1917a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1918f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1919f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
192017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
192117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
19226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1925831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
19263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1929b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
193087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
1931b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
1932b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      Existing->setLocation(Attr.getLoc());
1933b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
193487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
1935b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
19366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1939232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1940831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
19413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1942232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1943232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1944bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
194587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
1946b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
1947b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor     Existing->setLocation(Attr.getLoc());
1948b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
194987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1950b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
1951232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1952232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
19531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1954232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
19551731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1956232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1957bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
195887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1959232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1960232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
19611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1962bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1963f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1964f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1965f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1966bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1967f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1968f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1969f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1970f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1971bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
197287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
1973bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1974f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1975f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1976f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1977f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1978bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1979f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1980c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1981f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1982f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1983f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1984f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
1985f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1986f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1987f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1988f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1990f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1991f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
1992f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1993f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
1994f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1995f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1996f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1997f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1998f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
1999f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2000f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2001f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2002f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2003f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2004bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
200589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
200689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
200789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
200889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2009b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2010b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2011f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
201289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
201389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
201489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
201589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2016bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
201787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
2018223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
2019f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2020f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2021bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2022bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
20231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20241731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
20255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
20261731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
202787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
20285b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2029883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
20305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
20315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
203207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
203307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
203407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
203587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
203687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
20375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
203807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
20395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
20407a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
20415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2042ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2043ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
20445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
20455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
20465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
20475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2048bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
20505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
20515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
20525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
20535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2054bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2056bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
205707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
205807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
205907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
206007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
206107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
206207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
206307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
206407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
206507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
20665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
206787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2068bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
20705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
20715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
20725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
20736217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
20745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
20755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2076bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
20775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
20785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2079bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
208087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
20815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
20825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
20835b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
20846217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
20855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
20865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2087bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
20885b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
20895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2090bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2091bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
209287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
209307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
20945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
20955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
20962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
20972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
20982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
20992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
21002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
21013c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
21022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
21032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
21042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
21052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
21062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
21075f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
21082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
21092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
21102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
21112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
21122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
21132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
21142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
21152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
21162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
21172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
21182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
21192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
2120cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2121cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
21222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
21232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2124bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2125bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
21263c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
21273c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
21282b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
21292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
21302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2131521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2132521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
21331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
21341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
2135521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
2136521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2137521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2138521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2139521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
214087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2141b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2142b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2143b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2144b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
214587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2146b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2147b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2148b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2149b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2150b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2151b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2152b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2153b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2154521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2155521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2156521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2157521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2158521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
21597a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2160b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2161521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2162521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2163521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2164521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2165521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2166521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2167521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2168521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
21699f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2170521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2171521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2172521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2173521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2174521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2175521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
217687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
2177f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2178521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2179521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2180bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2181bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
21821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2184545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2185fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
21863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
21876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
21896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2190545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
21913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
21926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
21946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
219587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2196fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2197883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
21986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
220107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
220207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
220387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
220487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
22056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
22066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22075f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
22086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
22102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
22112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
22122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
22142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
22153c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22163c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
22173c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
22183c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2220fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
222101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
22226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
22267a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2227803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2228ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2229ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2230fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
22313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
22326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2236fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
22373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
22386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
22426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2243bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22444a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
22454a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
224607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
224707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
224807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
22494a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
22504a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
22514a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
22524a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
22531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
225587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
22566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2258085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2259fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2260fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2261085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2262085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
22632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2264390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2265390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2266803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2267390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2268fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2269fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
22706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2271bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
22726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
22736217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2274390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2275fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2276fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
22776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
22817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2282803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2283ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2284ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2285fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
22863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
22876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
22916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
229287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
22936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
22946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
229587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
22966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
22976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
22986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
23013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
23022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
23036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2304fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2305fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
23066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
23076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
23086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
23096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2310fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
23113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
23126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2315b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2316b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
231787c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
231887c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2319b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2320b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2321b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2322b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2323b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2324b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2325b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2326b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2327b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->setLocation(Attr.getLoc());
2328b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2329b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2330b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2331b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
233287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
2333cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
23342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
23356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
23366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
23381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
23396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
23401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
23416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
23436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
23450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
234687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
23470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
23480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
23490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
235087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
23510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
23520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2353fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2354883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
23556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
2359bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
23600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
23610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
23620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
23630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
236417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
236517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
23660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
23670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
23680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
23690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2370bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
23710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
23720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
237390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2374bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
237590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
237690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
23770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
23780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2379bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
23800c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
23810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
23820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
23830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
23840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
23850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
23860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
23870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2388bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
23890c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2390bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
23910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
23920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
23930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2394bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
23950c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
23960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2397bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2398bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2399bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
24006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2401cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
24026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
24061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
24076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
24097a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2410797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
24136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
24146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2415797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
24166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
241887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
2419f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
24206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2424545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
24253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
24266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2428bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2429bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2430bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2431bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
24326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2433545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2434cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
24354ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
24364ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
24374ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
24387a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
24394ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
24404ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
24414ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
24424ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
24434ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2444cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
24456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2447bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2448cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
244949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
24504ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
24514ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
24524ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
245349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
245449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2455396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
24564ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
24574ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2458396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2459396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2460396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2461cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2462cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2463cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2464cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
2465cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2466cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2467cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
2468cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
24696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2470fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2471d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2472bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2473fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2474bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2475bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2476bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
24771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2478fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2479fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2480fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2481fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
24821731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2483fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
24841731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2485fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2486fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2487fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
24880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2489fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2490fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2491210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
24925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2493fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2494fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2495210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2496210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2497fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2498fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2499fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
250073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2501210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2502fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
250373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
250473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
250573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
250673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
250773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
250873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
250973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
251073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
251173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
251273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
251373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
251473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
251573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
251673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
251773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
251873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2519fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2520fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2521fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2522fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2523210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
25240b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2525210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
25260b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
2527fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2528fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2529210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
25300b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2531fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2532fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2533fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2534fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2535162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2536fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2537fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2538fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2539fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2540fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2541fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2542fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2543fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
254473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2545183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
254673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
254773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
25482ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
254973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
255073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
255173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
255273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
255373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
255473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
255573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
255673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
255773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2558390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2559390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2560390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2561390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2562f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2563f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2564fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2565fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2566fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
25673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2568fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2569fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
25703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2571fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2572fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
257373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
257473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
257573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
257673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2577fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
25780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2579fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
25800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2581fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2582fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
258373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
258473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
258573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
258673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2587fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
25880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2589fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
25900b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2591fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2592fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2593fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
25940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2595fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
25960b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2597fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
25980b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2599fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2600fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2601fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
26020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2603fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2604aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2605aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2606aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2607aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2608fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2609aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2610aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2611aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2612aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2613fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
261473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
261573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
261673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2617f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2618f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2619f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2620f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2621f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2622f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2623f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2624f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2625f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
262673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2627fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2628fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
262973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
263073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2631fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2632fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2633fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2634162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2635ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2636a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2637ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2638fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2639fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
26400744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
26411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2642d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
26431731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2644d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2645e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
264687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2647d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2648883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2649d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2650d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2651bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
265287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2653d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2654d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
26551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
26565bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
26571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
26585bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
26591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2660bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
266187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
26625bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2663883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
26645bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
26655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2666bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
266787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
26685bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
26695bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
26701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
26711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
26727255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
26731731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
26747255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
26751731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
26767255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
267787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
26787255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2679883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
26807255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
26817255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
26827255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
268387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2684f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
26857255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
26867255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
26871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2688ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2689ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2690831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2691ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2692ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2693ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2694ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
269587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2696ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2697883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2698ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2699ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2700ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
270187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2702ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2703ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2704ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2705ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2706ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
27071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2708ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2709ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2710ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2711ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2712ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2713ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2714ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
271587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2716ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2717883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2718ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2719ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2720ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
272187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2722ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2723ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2724ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2725ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2726ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
27271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2728ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2729ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
27301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2731ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2732ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
273387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2734ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2735883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2736ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2737ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2738ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
273987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
27402c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2741723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
27422c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
27432c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
27442c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
27452c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
27462c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
27472c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
27482c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
27492c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
27502c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
27512c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
27522c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
27532c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
275487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2755ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2756ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2757ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2758ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2759ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
27601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2761ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2762ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
27631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2764ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
27651731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2766ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
276787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2768ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2769883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2770ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2771ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2772ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
277387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2774ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2775ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2776ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2777ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2778ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
27791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2780ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2781ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
27821731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2783ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
27841731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2785ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
278687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2787ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2788883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2789ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2790ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2791ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
279287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2793ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2794ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2795ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2796ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2797ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
27981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
279926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
28001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
280126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2802bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
280387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2804c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
280526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2806883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
280726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
280826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2809bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
28100130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2811cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2812c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2813c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2814bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
281587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
281626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
281726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
28181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
281987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2820711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
282187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2822e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2823711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
282487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
2825711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2826e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
282787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
282887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
282987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2830711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2831711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2832711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
283387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2834e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
283587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2836e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2837e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
283887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2839e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2840f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
284187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
284204633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2843e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
284487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2845e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
284652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
284787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
284852fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2849414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
285087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
2851414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
28525cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
285387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2854414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
285587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2856414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2857414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2858414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
28595f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2860414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2861414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2862414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2863414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2864414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2865414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
286687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
286787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2868414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2869414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2870414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
287187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PcsAttr(Attr.getLoc(), S.Context, PCS));
2872414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2873e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2874e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2875e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2876e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2877e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2878e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
28791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
288056aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
288187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2882f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2883f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2884711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2885711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2886711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2887711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2888831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
2889831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2890831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
2891711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2892711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2893711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2894ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
289555d3aaf9a537888734762170823daf750ea9036dEli Friedman
2896414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
2897414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
2898711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2899711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
2900711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2901711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2902711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2903711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2904414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2905414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2906414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
29075cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
2908414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2909414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2910414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2911414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
2912414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2913414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
29145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2915414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
2916414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
2917414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2918414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
2919414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
2920414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2921414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2922414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
2923414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2924711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
2925711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2926711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2927711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2928711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2929711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
29301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
293187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2932711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2933711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
293487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
2935711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2936711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
293787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
293887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
293987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2940ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2941ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
294255d3aaf9a537888734762170823daf750ea9036dEli Friedman
294387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, numParams));
2944711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2945711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2946711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
2947711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
294887c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
294987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
2950711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2951711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
295287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
295387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
295487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2955711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2956711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2957711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
295887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
295955d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2960ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2961711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
296287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
296355d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
296487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2965711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
296655d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
296755d3aaf9a537888734762170823daf750ea9036dEli Friedman
2968711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (Context.Target.getRegParmMax() == 0) {
296987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
297055d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
297187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2972711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
297355d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
297455d3aaf9a537888734762170823daf750ea9036dEli Friedman
2975711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
2976711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (numParams > Context.Target.getRegParmMax()) {
297787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2978711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
297987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2980711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
298155d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
298255d3aaf9a537888734762170823daf750ea9036dEli Friedman
2983711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2984ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2985ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
29861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
29877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
29887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
29897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
2990bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
2991bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
29927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
29937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
29947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
299587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
29967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2997883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
29987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
29997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
30017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
30027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
30037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
30047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
30057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
30067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
30077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
30087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
30097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
30117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
30127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
30137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
30147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
30157b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
30167b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
30177b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
30187b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
30197b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
30207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
30217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
302387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
30247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
30257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
30267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
30277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
30287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
30297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
30307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
30310744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3032b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3033b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3034b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3035c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
3036c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
3037c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3038c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
3039c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
3040c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3041c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
30421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
304387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3044c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
304587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
304687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedParameter;
3047c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3048c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3049c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3050c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
305187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3052c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3053c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3054c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3055c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3056c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3057c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3058c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3059c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
306087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
306187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << cf;
3062c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3063c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3064c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3065c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
306687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getLoc(), S.Context));
3067c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
306887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getLoc(), S.Context));
3069c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3070c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
30711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
30721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
307387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
307487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
307587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedMethod;
3076c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3077c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3078c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
307987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getLoc(), S.Context));
3080c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3081c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
30821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
30831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3084b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3085c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3086bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
308787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3088c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
308987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3090831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
309187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
309287c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3093f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
309487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3095c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
30965dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
309787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
309887c44604325578b8de07d768391c1c9432404f5aChandler Carruth        << SourceRange(Attr.getLoc()) << Attr.getName()
3099883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3100b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3101b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3102bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3103c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3104c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
310587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3106c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
3107c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3108c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3109c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3110c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3111c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3112c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3113c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3114c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3115c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3116c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3117c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3118c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3119c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3120c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3121c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
312287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
312387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc())
312487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3125bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
31265dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3127bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
312887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3129b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3130b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
3131b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3132c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
313387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getLoc(),
3134c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3135c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
313631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
313787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(),
3138f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
313931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
314031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
314187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(),
3142f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
314331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3144b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
314587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(),
3146f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3147b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3148b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
314987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(),
3150f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3151b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3152b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3153b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3154b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3155dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3156dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3157dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3158dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3159dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3160dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3161dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!isa<ObjCMethodDecl>(method)) {
3162dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type)
3163dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc, loc) << attr.getName() << 13 /* methods */;
3164dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3165dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3166dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3167dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3168dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3169dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!resultType->isPointerType() || resultType->isObjCRetainableType()) {
3170dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3171dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3172dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3173dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3174dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3175dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3176dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3177dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3178dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3179dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    ::new (S.Context) ObjCReturnsInnerPointerAttr(loc, S.Context));
3180dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3181dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
31821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
31831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
318487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3185f85e193739c953358c865005855253af4f68a497John McCall
318687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  SourceLocation L = Attr.getLoc();
318787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
318887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
3189f85e193739c953358c865005855253af4f68a497John McCall}
3190f85e193739c953358c865005855253af4f68a497John McCall
31911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
31921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
319387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
319487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    SourceLocation L = Attr.getLoc();
319587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
319687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
3197f85e193739c953358c865005855253af4f68a497John McCall    return;
3198f85e193739c953358c865005855253af4f68a497John McCall  }
3199f85e193739c953358c865005855253af4f68a497John McCall
320087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3201f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3202f85e193739c953358c865005855253af4f68a497John McCall
3203f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3204f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
320587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3206f85e193739c953358c865005855253af4f68a497John McCall      << type;
3207f85e193739c953358c865005855253af4f68a497John McCall    return;
3208f85e193739c953358c865005855253af4f68a497John McCall  }
3209f85e193739c953358c865005855253af4f68a497John McCall
3210f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3211f85e193739c953358c865005855253af4f68a497John McCall
3212f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3213f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3214f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3215f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3216f85e193739c953358c865005855253af4f68a497John McCall
3217f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3218f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3219f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3220f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3221f85e193739c953358c865005855253af4f68a497John McCall    break;
3222f85e193739c953358c865005855253af4f68a497John McCall
3223f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3224f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3225f85e193739c953358c865005855253af4f68a497John McCall    break;
3226f85e193739c953358c865005855253af4f68a497John McCall
3227f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3228f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
322987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3230f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3231f85e193739c953358c865005855253af4f68a497John McCall    break;
3232f85e193739c953358c865005855253af4f68a497John McCall  }
3233f85e193739c953358c865005855253af4f68a497John McCall
323487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
323587c44604325578b8de07d768391c1c9432404f5aChandler Carruth                 ObjCPreciseLifetimeAttr(Attr.getLoc(), S.Context));
3236f85e193739c953358c865005855253af4f68a497John McCall}
3237f85e193739c953358c865005855253af4f68a497John McCall
3238f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
3239f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
324011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
324111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
324211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
324311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
324411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
324511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
324611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
324711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
32481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
324911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
325011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
32511731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
325211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
32531731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
325411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
325511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
32565cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3257d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3258d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3259d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3260d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3261d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
32625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3263d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3264d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3265d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3266d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3267d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3268d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3269d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3270d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3271d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3272d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3273d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3274d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3275d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3276d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3277d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3278d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
32795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3280f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3281f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3282f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3283f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3284d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3285d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3286d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3287d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3288d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3289d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3290d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3291d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3292d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3293d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3294d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
329511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
329687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
329711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3298d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
329911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3300f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3301f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3302b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
33030744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
33040744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
33050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
33061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
33071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
330860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
33091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
33101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
33111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
331260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
331360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
331460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
331560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3316e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
33171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
33181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3319803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
33201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break;
33211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
3322857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
33231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3324803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3325207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3326ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
33276e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
33284211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
33294211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3330bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3332803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
333360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
333460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
333560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
333660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
333760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
333860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
33391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
33401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3341bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
33421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3343b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
33441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
33451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
33461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3347bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
33481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
33491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
33501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
33511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
33521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
33531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
33543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
33551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
33563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
33571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
33581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
33591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
33601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
33617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
33621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
33637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
33641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
33651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
33661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
33671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
33681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3369dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3370dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3371dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
33721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
33731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
33741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
33751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
33761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
33771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3378b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3379b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
33801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3381f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
33821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3383f85e193739c953358c865005855253af4f68a497John McCall
3384dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3385dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3386dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3387b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3388c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
33891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3390c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
33911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3392c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3393c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
339431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
339531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3396b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3397b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
33981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3399b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
34006f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
34011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
34026f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3403521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
34041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3405521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
34061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
34071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break;
34081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
34091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3410742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  case AttributeList::AT_arc_weakref_unavailable:
3411742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3412742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
34131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
34141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
34151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
34161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3417026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
34181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
34191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
34201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3421803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
34221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3423803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
34240db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
34251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
34260db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3427d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
34281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3429d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
34301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break;
34311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
34321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
34331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
34341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
34351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
34361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
34371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
34381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3439bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
344005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
344105f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
34427255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
34431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
34447255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
344504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
344604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
344704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3448f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
344952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3450414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
34511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
345204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3453f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
34541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3455f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
345611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
34571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
345811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3459fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3460fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3461fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3462fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3463fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3464fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3465fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3466fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3467fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3468fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3469fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3470fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3471fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3472fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3473fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3474fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3475fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3476db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3477db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3478db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3479db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3480db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3482db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3483db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3485db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3486db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3487db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3488db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3489db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3491db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3492db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3493db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3494db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3495db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3496db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3497db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3498db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3499db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3500db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3501db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3502db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3503db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3504db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3505db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3506db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3507db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3508db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3509db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3510db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3511db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3512db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3514db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3515fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3516803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
351782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
351882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
351982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
35207d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
35217d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3522803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3523803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3524803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3525803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
352660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
352760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
352860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
352960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
35301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
35311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
353260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
353360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
353460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
353560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
353660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
353760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
353860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
353960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
354060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
35411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
354260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
354360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
35441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
354560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
354660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3547803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3548803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3549f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
355060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
355160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
355211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
35531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
355411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
355511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
355611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
355711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
355811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
355960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
356011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3561dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
356211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3563803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3564803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3565803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
3566e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3567e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
35681eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
35697b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3570e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3571e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3572e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3573ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                FD->getInnerLocStart(),
3574e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
3575a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
3576b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
3577b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
3578c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3579b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3580e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3581e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3582ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3583a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
358416573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
358516573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3586b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3587b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3588c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3589b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3590e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3591e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3592e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3593e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3594e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3595e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
35967b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3597c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3598c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3599c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3600c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3601c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
3602cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3603cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3604cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3605c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3606c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3607c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3608c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3609c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3610c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3611c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3612c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3613cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3614e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3615e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3616e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
36170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
36180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
36190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
362060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
362160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3622d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3623d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
362431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
362531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
362631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
362731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
362831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
362931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
363031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
363131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
363231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
363331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
363431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
363531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3636d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3637e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3638e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3639e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3640e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
36410744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
36427f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
364360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3644bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
36450744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
36460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
36470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
36480744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
36490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
36500744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
365160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3652bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
36530744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
36540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
365560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
36560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
365754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3658f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3659f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3660f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3661f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3662f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3663f85e193739c953358c865005855253af4f68a497John McCall  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl))
3664f85e193739c953358c865005855253af4f68a497John McCall    return false;
3665f85e193739c953358c865005855253af4f68a497John McCall
3666f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3667f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3668f85e193739c953358c865005855253af4f68a497John McCall}
3669f85e193739c953358c865005855253af4f68a497John McCall
3670f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
3671f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3672f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
3673f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
3674f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3675f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
3676f85e193739c953358c865005855253af4f68a497John McCall    return;
3677f85e193739c953358c865005855253af4f68a497John McCall  }
3678f85e193739c953358c865005855253af4f68a497John McCall
3679f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3680f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3681f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
3682f85e193739c953358c865005855253af4f68a497John McCall}
3683f85e193739c953358c865005855253af4f68a497John McCall
3684eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3685eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3686eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3687eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3688eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3689eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3690eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3691eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3692eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3693eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3694eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3695eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3696eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3697eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3698eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3699eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3700eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3701eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3702eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3703eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3704eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
370554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
370654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3707eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3708eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
3709eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
371054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3711eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
3712eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
3713eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
3714eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
371554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3716eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
3717eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
371854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3719eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
3720eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
3721eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
372258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
37232f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
37242f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
3725a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis  if (decl && !decl->isInvalidDecl()) {
3726eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
3727eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
37282f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
37292f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
37302f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
37312f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
37322f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
3733eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3734eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
3735eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
37362f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
37372f514480c448708ec382a684cf5e035d3a827ec8John McCall
3738eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
37392f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
3740eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
37412f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
37422f514480c448708ec382a684cf5e035d3a827ec8John McCall
37432f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
3744eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
37452f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
3746f85e193739c953358c865005855253af4f68a497John McCall
3747f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
3748f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
3749f85e193739c953358c865005855253af4f68a497John McCall        break;
375054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
375154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
375254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
375354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
375458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
3755eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
375629233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
375758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
3758eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
37592f514480c448708ec382a684cf5e035d3a827ec8John McCall}
37602f514480c448708ec382a684cf5e035d3a827ec8John McCall
37612f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
37622f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
37630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
37642f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
37652f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
37662f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
37672f514480c448708ec382a684cf5e035d3a827ec8John McCall}
37682f514480c448708ec382a684cf5e035d3a827ec8John McCall
37699c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
37702f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
37712f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
37722f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
37732f514480c448708ec382a684cf5e035d3a827ec8John McCall
37742f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
3775ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
3776c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
3777ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
3778ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
3779c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
3780c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
3781ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
378254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
378354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
37845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
37858e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
378689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
378754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
3788eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3789eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
379054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
379154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
379254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
379354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
379454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
379554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
3796ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
3797c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3798c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
37998e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
3800743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
38018e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
380289ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
38038e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
380489ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
380589ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
38068e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
380754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
3808