SemaDeclAttr.cpp revision 08fc8eb5a1cc9c01af67e016ab21c9b905711eb1
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"
17bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins#include "clang/AST/CXXInheritance.h"
18384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
19b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski#include "clang/AST/DeclTemplate.h"
20acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
21acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
22f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h"
23fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2419510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
26fe98da0fa352462c02db037360788748f95466f7John McCall#include "clang/Sema/Lookup.h"
27797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
299c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of
32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
33b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskienum AttributeDeclKind {
34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunction,
35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedUnion,
36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableOrFunction,
37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionOrMethod,
38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameter,
39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrBlock,
40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrParameter,
41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClass,
42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariable,
43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedMethod,
44db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  ExpectedVariableFunctionOrLabel,
45f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor  ExpectedFieldOrGlobalVar,
465e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  ExpectedStruct,
475e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  ExpectedTLSVar
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) {
874ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky  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
243aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
244aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// Check to see if the type is a smart pointer of some kind.  We assume
245aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// it's a smart pointer if it defines both operator-> and operator*.
24660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchinsstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
24760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
24860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
24960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (Res1.first == Res1.second)
25060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return false;
25160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
25260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
25360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
25460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (Res2.first == Res2.second)
25560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return false;
25660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
25760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  return true;
258aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins}
259aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type.
261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message.
262fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise
263ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
264ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                       const AttributeList &Attr) {
26539997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
266fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
26739997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer    if (QT->isAnyPointerType())
268fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
269aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
27060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    if (const RecordType *RT = QT->getAs<RecordType>()) {
27160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // If it's an incomplete type, it could be a smart pointer; skip it.
27260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // (We don't want to force template instantiation if we can avoid it,
27360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // since that would alter the order in which templates are instantiated.)
27460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      if (RT->isIncompleteType())
27560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins        return true;
27660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
27760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      if (threadSafetyCheckIsSmartPointer(S, RT))
27860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins        return true;
27960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    }
280aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
281ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
282fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
283fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
284fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
285fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
286fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
287fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
288fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
289fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
290b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points
291b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit.
2927d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) {
2937d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const RecordType *RT = QT->getAs<RecordType>())
294b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return RT;
2957d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2967d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  // Now check if we point to record type.
2977d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const PointerType *PT = QT->getAs<PointerType>())
2987d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer    return PT->getPointeeType()->getAs<RecordType>();
2997d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
3007d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  return 0;
301b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
302b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
303bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
304fad5de9d674521017460f8445e2f81e2a1086290Jordy Rosestatic bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
305fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                             CXXBasePath &Path, void *Unused) {
306bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  const RecordType *RT = Specifier->getType()->getAs<RecordType>();
307bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (RT->getDecl()->getAttr<LockableAttr>())
308bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    return true;
309bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  return false;
310bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins}
311bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
312bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
3133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType
314ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// resolves to a lockable object.
31583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchinsstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
31683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins                                   QualType Ty) {
31783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  const RecordType *RT = getRecordType(Ty);
31808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
31983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  // Warn if could not get record type for this argument.
320d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT) {
321ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
32283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      << Attr.getName() << Ty.getAsString();
32383cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
3243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
32560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
32608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  // Don't check for lockable if the class hasn't been defined yet.
327634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  if (RT->isIncompleteType())
32883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
32960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
33060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  // Allow smart pointers to be used as lockable objects.
33160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  // FIXME -- Check the type that the smart pointer points to.
33260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (threadSafetyCheckIsSmartPointer(S, RT))
33360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return;
33460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
335bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  // Check if the type is lockable.
336bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  RecordDecl *RD = RT->getDecl();
337bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (RD->getAttr<LockableAttr>())
33883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
339bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
340bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  // Else check if any base classes are lockable.
341bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
342bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    CXXBasePaths BPaths(false, false);
343bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths))
344bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins      return;
3453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
346bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
347bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
348bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    << Attr.getName() << Ty.getAsString();
3493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
351b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
352ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// from Sidx, resolve to a lockable object.
3533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with.
3543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function
3553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list.
356ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
3573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         const AttributeList &Attr,
3583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         SmallVectorImpl<Expr*> &Args,
359b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
360b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
3613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
362b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
3633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
364ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    if (ArgExp->isTypeDependent()) {
365ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // FIXME -- need to check this again on template instantiation
366ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      Args.push_back(ArgExp);
367ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      continue;
368ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    }
369b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
37079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
37179747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      // Ignore empty strings without warnings
37279747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (StrLit->getLength() == 0)
37379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        continue;
37479747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
375ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // We allow constant strings to be used as a placeholder for expressions
376ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // that are not valid C++ syntax, but warn that they are ignored.
377ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
378ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins        Attr.getName();
379ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      continue;
380ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    }
381ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins
3823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
383b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
38479747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // A pointer to member expression of the form  &MyClass::mu is treated
38579747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // specially -- we need to look at the type of the member.
38679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
38779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (UOp->getOpcode() == UO_AddrOf)
38879747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
38979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins          if (DRE->getDecl()->isCXXInstanceMember())
39079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins            ArgTy = DRE->getDecl()->getType();
39179747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
3923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
394b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
398b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
399b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
400b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
401b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
4023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
4033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
4043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
405b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
406b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
407ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins          continue;
408b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
4093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
410b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
411b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
412b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
41383cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    checkForLockableRecord(S, D, Attr, ArgTy);
414b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
416b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
417b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
418b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
419e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
420e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
421e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
422e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
4233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
4243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
4253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
4263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4270aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchinsenum ThreadAttributeDeclKind {
4280aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins  ThreadExpectedFieldOrGlobalVar,
4290aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins  ThreadExpectedFunctionOrMethod,
4300aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins  ThreadExpectedClassOrStruct
4310aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins};
4320aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins
43308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkGuardedVarAttrCommon(Sema &S, Decl *D,
434dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                      const AttributeList &Attr) {
435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
438dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
440fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
4420aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
4430aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
444dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
446fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
447dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
448dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
449dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
450dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Hanstatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) {
451dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkGuardedVarAttrCommon(S, D, Attr))
452fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
453fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
454dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
455fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
456fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
45708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handlePtGuardedVarAttr(Sema &S, Decl *D,
458dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                           const AttributeList &Attr) {
459dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkGuardedVarAttrCommon(S, D, Attr))
460dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
462dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!threadSafetyCheckIsPointer(S, D, Attr))
463db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
464db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
465dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
466fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
467fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
46808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkGuardedByAttrCommon(Sema &S, Decl *D,
46908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                     const AttributeList &Attr,
470dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                     Expr* &Arg) {
471db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
472db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
473b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
474dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
4753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
476db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
477db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
4780aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
4790aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
480dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
482db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
483ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  SmallVector<Expr*, 1> Args;
484ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // check that all arguments are lockable objects
485ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
486ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  unsigned Size = Args.size();
487ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size != 1)
488dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
489db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
490dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Arg = Args[0];
491b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
492dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
493dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
494dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
495dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Hanstatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) {
496dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr *Arg = 0;
497dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
498ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
499b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
500dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
501db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
502db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
50308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handlePtGuardedByAttr(Sema &S, Decl *D,
504dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                  const AttributeList &Attr) {
505dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr *Arg = 0;
506dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
507dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
508dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
509dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!threadSafetyCheckIsPointer(S, D, Attr))
510dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
511dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
512dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
513dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                               S.Context, Arg));
514dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
515db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
51608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkLockableAttrCommon(Sema &S, Decl *D,
517dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                    const AttributeList &Attr) {
518fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
519fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
520fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
521dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
522fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
5231748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
524fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
5250aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
5260aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedClassOrStruct;
527dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
528fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
529fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
530dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
531dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
532dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
533dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Hanstatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
534dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLockableAttrCommon(S, D, Attr))
535dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
536dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
537dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
538dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
539dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
54008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleScopedLockableAttr(Sema &S, Decl *D,
541dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                             const AttributeList &Attr) {
542dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLockableAttrCommon(S, D, Attr))
543dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
544dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
545dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
546fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
547fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
548fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
549fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
550fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
551fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
552fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
553fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
554fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
555b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
5560aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
5570aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
558fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
559fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
560fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
561768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
562fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
563fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
564fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
56571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D,
566ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                      const AttributeList &Attr) {
56771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  assert(!Attr.isInvalid());
56871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
56971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!checkAttributeNumArgs(S, Attr, 0))
57071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
57171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
57271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
57371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
57471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany      << Attr.getName() << ExpectedFunctionOrMethod;
57571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
57671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  }
57771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
57871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
579f50b6fe092091a700cee7a708d509ae7c49709f6Nick Lewycky                                                           S.Context));
58071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany}
58171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
58208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
58308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                        const AttributeList &Attr,
584dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                        SmallVector<Expr*, 1> &Args) {
585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
586db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
587b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
588dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
591b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
592b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
5930aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
5940aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
595dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
596db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
597db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
598ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that this attribute only applies to lockable types.
599b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
600b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
601b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
602b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
603ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
604dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han        << Attr.getName();
605dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han      return false;
606b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
607b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
608b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
609ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that all arguments are lockable objects.
610ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
611dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (Args.size() == 0)
612dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
61308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
614dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
615dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
616dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
61708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleAcquiredAfterAttr(Sema &S, Decl *D,
618dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                    const AttributeList &Attr) {
6193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
620dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
621b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
622b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
623ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
624dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
6254ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky                                                 StartArg, Args.size()));
626dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
6273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
62808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleAcquiredBeforeAttr(Sema &S, Decl *D,
629dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                     const AttributeList &Attr) {
630dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  SmallVector<Expr*, 1> Args;
631dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
632dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
633dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
634dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr **StartArg = &Args[0];
635dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
6364ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky                                                  StartArg, Args.size()));
637db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
638db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
63908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkLockFunAttrCommon(Sema &S, Decl *D,
64008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                   const AttributeList &Attr,
641dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                   SmallVector<Expr*, 1> &Args) {
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
645db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
646b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
647b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
6480aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
6490aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
650dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
651db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
652db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
653b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
654ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
655dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
656dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
657dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
658dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
65908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleSharedLockFunctionAttr(Sema &S, Decl *D,
660dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                         const AttributeList &Attr) {
6613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
662dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLockFunAttrCommon(S, D, Attr, Args))
663b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
664b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
667dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
66808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                      S.Context,
669dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                      StartArg, Size));
670dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
6713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
67208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
673dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                            const AttributeList &Attr) {
674dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  SmallVector<Expr*, 1> Args;
675dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLockFunAttrCommon(S, D, Attr, Args))
676dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
677dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
678dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  unsigned Size = Args.size();
679dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr **StartArg = Size == 0 ? 0 : &Args[0];
680dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
68108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                         S.Context,
682dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                         StartArg, Size));
683db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
684db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
68508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
68608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                      const AttributeList &Attr,
687dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                      SmallVector<Expr*, 2> &Args) {
688db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
689db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
690b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
691dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
692b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
693b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
6940aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
6950aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
696dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
697db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
698db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
699b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
700b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
701dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han      << Attr.getName();
702dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
703b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
704b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
705b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
706ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
707dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
708dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
709dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
710dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
71108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
712dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                            const AttributeList &Attr) {
713dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  SmallVector<Expr*, 2> Args;
714dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
715b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
716b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
7173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
7183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
719dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
72008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                         S.Context,
72108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                         Attr.getArg(0),
722dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                         StartArg, Size));
723dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
7243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
72508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
726dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                               const AttributeList &Attr) {
727dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  SmallVector<Expr*, 2> Args;
728dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
729dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
730dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
731dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  unsigned Size = Args.size();
732dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr **StartArg = Size == 0 ? 0 : &Args[0];
733dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
73408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                            S.Context,
73508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                            Attr.getArg(0),
736dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                            StartArg, Size));
737db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
738db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
73908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkLocksRequiredCommon(Sema &S, Decl *D,
74008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                     const AttributeList &Attr,
741dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                     SmallVector<Expr*, 1> &Args) {
742db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
743db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
744b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
745dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
746db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
747b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
7480aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
7490aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
750dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
751db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
752db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
753b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
754ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
755dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (Args.size() == 0)
756dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
75708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
758dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
759dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
760dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
76108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D,
762dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                             const AttributeList &Attr) {
7633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
764dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLocksRequiredCommon(S, D, Attr, Args))
765b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
766b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
767ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
768dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
76908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                          S.Context,
77008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                          StartArg,
771dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                          Args.size()));
772dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
7733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
77408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleSharedLocksRequiredAttr(Sema &S, Decl *D,
775dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                          const AttributeList &Attr) {
776dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  SmallVector<Expr*, 1> Args;
777dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLocksRequiredCommon(S, D, Attr, Args))
778dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
779dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
780dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr **StartArg = &Args[0];
781dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
78208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                       S.Context,
78308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                       StartArg,
784dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                       Args.size()));
785db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
786db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
787db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
788b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
789db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
790db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
791db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
792db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
793b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
7940aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
7950aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
796db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
797db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
798db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
799b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
8003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
801ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
8023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
8033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
8043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
805768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
8063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
807db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
808db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
809db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
810b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
811db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
812db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
813b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
814db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
8153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
816db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
817b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
8180aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
8190aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
820db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
821db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
822db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
8233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
824b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
825b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
8263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
827f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  SmallVector<Expr*, 1> Args;
828f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
829f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  unsigned Size = Args.size();
830f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  if (Size == 0)
831f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins    return;
8323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
833f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context,
834f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins                                                Args[0]));
835db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
836db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
837db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
838b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
839db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
840db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
841b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
842db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
843db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
844b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
8450aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
8460aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
847db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
848db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
849db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
850b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
8513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
852ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
8533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
854ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
855ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
856ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
8573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
858768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
8593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
860db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
861db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
862db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
8631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
8641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
86587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
866545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
867803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
868545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
8696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
870bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
8716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
8729cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
8739cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
8749cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
8759cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
8769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
877f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
878e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    SourceLocation TemplateKWLoc;
879f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
880f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
88108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
882e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id,
883e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                          false, false);
8844ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
8854ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
88608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
8874ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
8889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
8899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
8901731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
8919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
8921731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
8937a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
8946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
8969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
8979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
8989ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
8999cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
900ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
901a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
902bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
9039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
9049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
9056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
9096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
9101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
9116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
912bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
91387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
914768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
91587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
9166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
9176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
9186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
919803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
920fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
92108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
9226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
923768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
9246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
9253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
9266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
92987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
930768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
931c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
932c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
933c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
934c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
9351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
93696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
9371731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
93896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
939bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
94063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
94187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
94263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
943768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
94463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
94563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
94663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
9474ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
94863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
94963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
9502f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
9512f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // The IBOutlet/IBOutletCollection attributes only apply to instance
9522f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // variables or properties of Objective-C classes.  The outlet must also
9532f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // have an object reference type.
9542f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
9552f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
9560bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
9572f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << VD->getType() << 0;
9582f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
9592f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
9602f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
9612f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
9622f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
963f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
9642f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << PD->getType() << 1;
9652f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
9662f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
9672f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
9682f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else {
9692f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
9702f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    return false;
9712f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
972f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
9732f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  return true;
9742f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek}
9752f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
9761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
97763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
9781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
97963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
98008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
9812f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
98263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
98363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
9842f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
98596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
98696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
9871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
9881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
989857e918a8a40deb128840308a318bf623d68295fTed Kremenek
990857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
991a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
992857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
993857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
994857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
995857e918a8a40deb128840308a318bf623d68295fTed Kremenek
9962f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
997857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
9982f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
999a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
1000a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
1001f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian    II = &S.Context.Idents.get("NSObject");
100208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
100308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
100487c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
1005a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
1006a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
1007a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
1008a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
1009b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
1010a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
1011a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
1012a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
1013a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
1014f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
1015a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
1016a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
1017a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
1018f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
1019f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
1020857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
1021857e918a8a40deb128840308a318bf623d68295fTed Kremenek
1022d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
102368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
102468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
102568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
102668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
102768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
102868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
102968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
103068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
103168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
103268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
103368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
103468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
103568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
103668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
1037587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopesstatic void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1038174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes  if (!isFunctionOrMethod(D)) {
1039174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1040174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes    << "alloc_size" << ExpectedFunctionOrMethod;
1041174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes    return;
1042174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes  }
1043174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes
1044587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
1045587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    return;
1046587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1047587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  // In C++ the implicit 'this' function parameter also counts, and they are
1048587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  // counted from one.
1049587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  bool HasImplicitThisParam = isInstanceMethod(D);
1050587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1051587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1052587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  SmallVector<unsigned, 8> SizeArgs;
1053587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1054587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  for (AttributeList::arg_iterator I = Attr.arg_begin(),
1055587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes       E = Attr.arg_end(); I!=E; ++I) {
1056587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    // The argument must be an integer constant expression.
1057587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    Expr *Ex = *I;
1058587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    llvm::APSInt ArgNum;
1059587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
1060587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
1061587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1062587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      << "alloc_size" << Ex->getSourceRange();
1063587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      return;
1064587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
1065587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1066587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    uint64_t x = ArgNum.getZExtValue();
1067587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1068587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (x < 1 || x > NumArgs) {
1069587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1070587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      << "alloc_size" << I.getArgNum() << Ex->getSourceRange();
1071587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      return;
1072587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
1073587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1074587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    --x;
1075587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (HasImplicitThisParam) {
1076587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      if (x == 0) {
1077587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        S.Diag(Attr.getLoc(),
1078587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes               diag::err_attribute_invalid_implicit_this_argument)
1079587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        << "alloc_size" << Ex->getSourceRange();
1080587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        return;
1081587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      }
1082587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      --x;
1083587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
1084587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1085587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    // check if the function argument is of an integer type
1086587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
1087587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (!T->isIntegerType()) {
1088587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1089587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      << "alloc_size" << Ex->getSourceRange();
1090587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      return;
1091587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
1092587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1093587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    SizeArgs.push_back(x);
1094587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  }
1095587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1096587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  // check if the function returns a pointer
1097587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  if (!getFunctionType(D)->getResultType()->isAnyPointerType()) {
1098587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
1099587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    << "alloc_size" << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange();
1100587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  }
1101587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
110296c67d1c2aff532729c9edb297617094d1e77cc1Nuno Lopes  D->addAttr(::new (S.Context) AllocSizeAttr(Attr.getRange(), S.Context,
110396c67d1c2aff532729c9edb297617094d1e77cc1Nuno Lopes                                             SizeArgs.data(), SizeArgs.size()));
1104587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes}
1105587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
11061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1107bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
1108bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
110987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
1110fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1111883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1112eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
1113eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
1114bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
111507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
111607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
111787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
111887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1119eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
1120eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
11215f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
1122bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1123eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
1124eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
1125bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1126bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1127eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
11287a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
1129eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
1130ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
1131ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
1132fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1133fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
1134eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
1135eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
1136bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1137eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1139eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
1140fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
114130bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
1142eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
1143eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
1144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1145465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
114607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
114707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
114807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
114907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
115007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
115107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
115207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
115307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
115407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
1155eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
1156eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
115787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
1158d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
115908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1160dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1161eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
1162c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
1163fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
11647fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
1165eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
1166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1167eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
1168eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
1169bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
1171bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
11727fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
117387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
117487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
1175d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
1176dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
1177d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
117846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
1179bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1180ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
118160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
118260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
118360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
118460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
118560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
11867fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
118760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
1188eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
11897fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
11907fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
11917fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
1192dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1193768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
1194cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
1195eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
1196eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
11971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
1198dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
1199dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
1200dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
1201dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
1202dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
1203dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
12042a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
12052a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
1206dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1207dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
1208dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
1209dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
1210dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1211dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1212dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
1213cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
12142a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
12152a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
1216cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
1217dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
1218dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1219dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1220dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
12212a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
12222a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
1223cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
1224dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
1225dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1226dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1227dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
12282a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
12292a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
1230cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
1231dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
1232dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
1233dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
1234dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1235dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
12362a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
12372a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
12382a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
12392a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
1240dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1241dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
124287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
1243883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1244883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
1245dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1246dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1247dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
124807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
124907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
125087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
125187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1252dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
12535f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
1254dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1255dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
1256dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
1257dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
1258dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
12595f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
1260dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
12612a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
12622a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1263dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
12647a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1265dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1266dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1267dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1268dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1269dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1270dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1271dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1272dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1273dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1274dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1275dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1276dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1277dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1278dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1279dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1280dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
128107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
128207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
128307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
128407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
128507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
128607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
128707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
128807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
128907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1290dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1291cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1292cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1293dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
129487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1295dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1296dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1297dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1298cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1299dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1300dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1301dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1302dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1303dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1304dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1305cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1306dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1307dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
13087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1309dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1310dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1311dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1312dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1313dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1314dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1315dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1316dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1317dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1318dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1319dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1320dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1321dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1322dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1323cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
132487c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
132587c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1326cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1327cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1328cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1329cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1330cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1331cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1332cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1333dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1334dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1335dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1336dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1337dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1338dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1339dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1340dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1341dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1342dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1343cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1344cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1345cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1346cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1347dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1348cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
134987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1350cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1351dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1352dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1353332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1354332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1355332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1356332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1357332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1358332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1359332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1360332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1361332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1362332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1363332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1364332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1365332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1366332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1367332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1368332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1369332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
137011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
137111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
13721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
137311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
137411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
137511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
137611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
137711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
137811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
137987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1380332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1381883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1382332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1383332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1384332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
138587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1386332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
138711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
138811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
138911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
139011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
139111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
139211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
139311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
139411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
139511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
139611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
139787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
13987a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
13997a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1400332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
14017a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
140211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
140311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
140411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
140511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
140611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
140711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
140811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
140911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
141011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
141111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
141211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
141311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
141411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
141511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
141611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
141711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
141811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
141911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
142011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
142111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1422332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1423332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
142411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
142511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
142611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
142711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
142811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
142911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
143011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
143111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
14327a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
143311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
143411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
143511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
14365cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
143711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
143811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
143911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
144011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
144111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
144211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1443768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1444f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
144511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
144611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1447768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
144811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
144911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
14501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1452545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
14533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
14546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1456bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14577a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
14586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
14596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1460bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14615cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1462fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
14633c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
14646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1466bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1467bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1468f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1469f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1470f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1471f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
14726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1473bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1474768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1475f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
14766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1478ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramerstatic void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1479ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  // Check the attribute arguments.
1480ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!checkAttributeNumArgs(S, Attr, 0))
1481ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1482ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1483ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!isa<FunctionDecl>(D)) {
1484ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1485ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << ExpectedFunction;
1486ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1487ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1488ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1489ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (D->hasAttr<HotAttr>()) {
1490ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1491ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << "hot";
1492ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1493ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1494ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1495ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context));
1496ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer}
1497ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1498ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramerstatic void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1499ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  // Check the attribute arguments.
1500ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!checkAttributeNumArgs(S, Attr, 0))
1501ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1502ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1503ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!isa<FunctionDecl>(D)) {
1504ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1505ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << ExpectedFunction;
1506ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1507ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1508ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1509ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (D->hasAttr<ColdAttr>()) {
1510ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1511ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << "cold";
1512ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1513ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1514ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1515ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context));
1516ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer}
1517ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
15181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1519dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
15201731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1521dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1522dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
152387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1524dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1525883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1526dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1527dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1528dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1529768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1530dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1531dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
15321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
15331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1534dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1535831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
15363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1537af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1538af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
15395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
154087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
15415bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1542883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
15445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1545bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1546768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1547af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1548af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
15495e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborgstatic void handleTLSModelAttr(Sema &S, Decl *D,
15505e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg                               const AttributeList &Attr) {
15515e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  // Check the attribute arguments.
15525e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  if (Attr.getNumArgs() != 1) {
15535e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
15545e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    return;
15555e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  }
15565e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
15575e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  Expr *Arg = Attr.getArg(0);
15585e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  Arg = Arg->IgnoreParenCasts();
15595e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
15605e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
15615e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  // Check that it is a string.
15625e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  if (!Str) {
15635e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    S.Diag(Attr.getLoc(), diag::err_attribute_not_string) << "tls_model";
15645e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    return;
15655e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  }
15665e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
15675e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->isThreadSpecified()) {
15685e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
15695e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg      << Attr.getName() << ExpectedTLSVar;
15705e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    return;
15715e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  }
15725e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
15735e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  // Check that the value.
15745e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  StringRef Model = Str->getString();
15755e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  if (Model != "global-dynamic" && Model != "local-dynamic"
15765e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg      && Model != "initial-exec" && Model != "local-exec") {
15775e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    S.Diag(Attr.getLoc(), diag::err_attr_tlsmodel_arg);
15785e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    return;
15795e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  }
15805e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
15815e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  D->addAttr(::new (S.Context) TLSModelAttr(Attr.getRange(), S.Context,
15825e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg                                            Model));
15835e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg}
15845e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
15851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1586dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1587831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
158876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
158976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
159076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
15911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
159287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
15931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
15942cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1595768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
15962cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
15972cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1598fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1599fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
16002cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
160176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
160276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
16031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
160434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
16051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
160634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
160734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1608768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
160934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
161034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
16111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
161256aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
161387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1614768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1615722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1616722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1617883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1618a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1619a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
16201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
162156aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
162287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1623768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1624722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1625722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1626883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1627a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1628a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
16291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
163087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1631711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1632711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1633711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
163487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1635711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1636883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1637711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1638711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1639711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1640768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1641711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1642711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1643711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1644831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1645711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1646711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1647711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1648711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1649711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1650711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1651b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1652b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
16531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
16541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
165508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1656b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1657b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
165808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
16591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
16601731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
166108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
166287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
166387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
16643ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
16653ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1666e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1667e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1668b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1669883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1670b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
167119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
16726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
167308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1674768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
16756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
16766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
167735cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
16781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
167935cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
168035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
168108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
168208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  According to the PPU ABI specifications, a class with a single member of
1683f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1684f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1685f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1686f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
168708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
168835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
168908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
169035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
169135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
169235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
169335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
169408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
169535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
169635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
169735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
169835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
169935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
170035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
170135cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
170287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
170335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1704883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
170535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
170635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
170735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
170887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
170935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
171035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
171135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
171235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
171387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
171401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
171501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
171601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
171701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
171801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
171901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
172001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
172101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
172201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
172301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
172401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
172501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1726f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1727f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
172801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
172901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
173001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
173101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
173201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
173301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
173401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1735768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
173635cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
173735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
17381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
173987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1740bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1741883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1742bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1743bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1744bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1745bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1746bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
17471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
174873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1749831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
17503c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
175173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
175273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1753bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
175487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
1755568eae48a4e19c0359cdcd2a33b8ec9812e4abbcDaniel Jasper      !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) {
1756fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1757883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
175873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
175973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1760bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1761768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
176273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
176373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1764f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1765f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1766f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1767f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1768f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1769f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1770f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1771f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1772f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1773f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1774f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1775f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1776f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1777f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1778f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1779f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1780f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
17811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1782b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1783831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1784b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1785b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1786b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1787bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
178887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1789186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1790b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1791b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1792b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
179387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1794b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1795883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1796b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1797b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1798bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1799768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1800b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1801b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
18021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1804bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1805bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
18063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1807bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
18083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
18093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
18103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
18117a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
18123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1813ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1814ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1815fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
18173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
18183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
18193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
18203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1821bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
182287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1823fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1824883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
18253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
18263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
18273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1828768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1829f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
18303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
18313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
18321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1834bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1835bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
18363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1837bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
18383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
18393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
18403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
18417a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
18423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1843ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1844ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1845fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
18473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
18483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
18493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
18503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1851bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
185287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1853fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1854883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
18553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
18563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
18573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1858768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1859f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
18603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
18613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1862bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramertemplate <typename AttrTy>
1863bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramerstatic void handleAttrWithMessage(Sema &S, Decl *D, const AttributeList &Attr,
1864bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer                                  const char *Name) {
1865951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1866951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1867bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1868c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1869c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1870bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer
1871bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer  // Handle the case where the attribute has a text message.
18725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1873951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1874951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1875c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1876951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1877bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer        << Name;
1878c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1879c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1880951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
18816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1882bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1883bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer  D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str));
1884bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1885bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
188608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1887742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1888742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1889742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1890742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1891742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1892742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
189308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1894742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1895768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1896742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1897742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
189808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleObjCRootClassAttr(Sema &S, Decl *D,
1899b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard                                    const AttributeList &Attr) {
1900b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (!isa<ObjCInterfaceDecl>(D)) {
1901b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1902b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1903b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
190408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1905b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  unsigned NumArgs = Attr.getNumArgs();
1906b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (NumArgs > 0) {
1907b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1908b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1909b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
191008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1911b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
1912b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard}
1913b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
191408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
1915e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                            const AttributeList &Attr) {
1916341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  if (!isa<ObjCInterfaceDecl>(D)) {
1917341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
1918341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    return;
1919341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  }
192008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1921e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1922e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  if (NumArgs > 0) {
1923e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1924e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    return;
1925e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  }
192608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
192771207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
1928e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                 Attr.getRange(), S.Context));
1929e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian}
1930e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
1931fad5de9d674521017460f8445e2f81e2a1086290Jordy Rosestatic bool checkAvailabilityAttr(Sema &S, SourceRange Range,
1932fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  IdentifierInfo *Platform,
1933fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  VersionTuple Introduced,
1934fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  VersionTuple Deprecated,
1935fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  VersionTuple Obsoleted) {
19365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
19370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
19383b294360febd89e3383143af086efe2014571afaRafael Espindola  if (PlatformName.empty())
19390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
19400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1941c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
19420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
19433b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Introduced.empty() && !Deprecated.empty() &&
19443b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Introduced <= Deprecated)) {
19453b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
19463b294360febd89e3383143af086efe2014571afaRafael Espindola      << 1 << PlatformName << Deprecated.getAsString()
19473b294360febd89e3383143af086efe2014571afaRafael Espindola      << 0 << Introduced.getAsString();
19483b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
19490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
19500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
19513b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Introduced.empty() && !Obsoleted.empty() &&
19523b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Introduced <= Obsoleted)) {
19533b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
19543b294360febd89e3383143af086efe2014571afaRafael Espindola      << 2 << PlatformName << Obsoleted.getAsString()
19553b294360febd89e3383143af086efe2014571afaRafael Espindola      << 0 << Introduced.getAsString();
19563b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
19570a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
19580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
19593b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Deprecated.empty() && !Obsoleted.empty() &&
19603b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Deprecated <= Obsoleted)) {
19613b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
19623b294360febd89e3383143af086efe2014571afaRafael Espindola      << 2 << PlatformName << Obsoleted.getAsString()
19633b294360febd89e3383143af086efe2014571afaRafael Espindola      << 1 << Deprecated.getAsString();
19643b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
19653b294360febd89e3383143af086efe2014571afaRafael Espindola  }
19663b294360febd89e3383143af086efe2014571afaRafael Espindola
19673b294360febd89e3383143af086efe2014571afaRafael Espindola  return false;
19683b294360febd89e3383143af086efe2014571afaRafael Espindola}
19693b294360febd89e3383143af086efe2014571afaRafael Espindola
1970599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaAvailabilityAttr *Sema::mergeAvailabilityAttr(Decl *D, SourceRange Range,
1971599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              IdentifierInfo *Platform,
1972599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              VersionTuple Introduced,
1973599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              VersionTuple Deprecated,
1974599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              VersionTuple Obsoleted,
1975599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              bool IsUnavailable,
1976599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              StringRef Message) {
197798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VersionTuple MergedIntroduced = Introduced;
197898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VersionTuple MergedDeprecated = Deprecated;
197998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VersionTuple MergedObsoleted = Obsoleted;
19803b294360febd89e3383143af086efe2014571afaRafael Espindola  bool FoundAny = false;
19813b294360febd89e3383143af086efe2014571afaRafael Espindola
198298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  if (D->hasAttrs()) {
198398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    AttrVec &Attrs = D->getAttrs();
198498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    for (unsigned i = 0, e = Attrs.size(); i != e;) {
198598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
198698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (!OldAA) {
198798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        ++i;
198898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
198998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
199098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
199198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      IdentifierInfo *OldPlatform = OldAA->getPlatform();
199298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (OldPlatform != Platform) {
199398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        ++i;
199498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
199598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
199698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
199798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      FoundAny = true;
199898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple OldIntroduced = OldAA->getIntroduced();
199998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple OldDeprecated = OldAA->getDeprecated();
200098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple OldObsoleted = OldAA->getObsoleted();
200198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      bool OldIsUnavailable = OldAA->getUnavailable();
200298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      StringRef OldMessage = OldAA->getMessage();
200398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
200498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if ((!OldIntroduced.empty() && !Introduced.empty() &&
200598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola           OldIntroduced != Introduced) ||
200698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (!OldDeprecated.empty() && !Deprecated.empty() &&
200798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola           OldDeprecated != Deprecated) ||
200898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (!OldObsoleted.empty() && !Obsoleted.empty() &&
200998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola           OldObsoleted != Obsoleted) ||
201098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (OldIsUnavailable != IsUnavailable) ||
201198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (OldMessage != Message)) {
201298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
201398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Diag(Range.getBegin(), diag::note_previous_attribute);
201498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Attrs.erase(Attrs.begin() + i);
201598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        --e;
201698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
201798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
201898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
201998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple MergedIntroduced2 = MergedIntroduced;
202098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple MergedDeprecated2 = MergedDeprecated;
202198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple MergedObsoleted2 = MergedObsoleted;
202298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
202398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (MergedIntroduced2.empty())
202498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        MergedIntroduced2 = OldIntroduced;
202598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (MergedDeprecated2.empty())
202698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        MergedDeprecated2 = OldDeprecated;
202798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (MergedObsoleted2.empty())
202898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        MergedObsoleted2 = OldObsoleted;
202998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
203098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
203198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola                                MergedIntroduced2, MergedDeprecated2,
203298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola                                MergedObsoleted2)) {
203398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Attrs.erase(Attrs.begin() + i);
203498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        --e;
203598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
203698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
203798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
203898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      MergedIntroduced = MergedIntroduced2;
203998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      MergedDeprecated = MergedDeprecated2;
204098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      MergedObsoleted = MergedObsoleted2;
204198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      ++i;
204298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    }
20430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
20440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
20453b294360febd89e3383143af086efe2014571afaRafael Espindola  if (FoundAny &&
20463b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedIntroduced == Introduced &&
20473b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedDeprecated == Deprecated &&
20483b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedObsoleted == Obsoleted)
2049599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return NULL;
20503b294360febd89e3383143af086efe2014571afaRafael Espindola
205198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
20523b294360febd89e3383143af086efe2014571afaRafael Espindola                             MergedDeprecated, MergedObsoleted)) {
2053599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return ::new (Context) AvailabilityAttr(Range, Context, Platform,
2054599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                            Introduced, Deprecated,
2055599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                            Obsoleted, IsUnavailable, Message);
20560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
2057599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return NULL;
20583b294360febd89e3383143af086efe2014571afaRafael Espindola}
20590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
20603b294360febd89e3383143af086efe2014571afaRafael Espindolastatic void handleAvailabilityAttr(Sema &S, Decl *D,
20613b294360febd89e3383143af086efe2014571afaRafael Espindola                                   const AttributeList &Attr) {
20623b294360febd89e3383143af086efe2014571afaRafael Espindola  IdentifierInfo *Platform = Attr.getParameterName();
20633b294360febd89e3383143af086efe2014571afaRafael Espindola  SourceLocation PlatformLoc = Attr.getParameterLoc();
20643b294360febd89e3383143af086efe2014571afaRafael Espindola
20653b294360febd89e3383143af086efe2014571afaRafael Espindola  if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty())
20663b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
20673b294360febd89e3383143af086efe2014571afaRafael Espindola      << Platform;
20680a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
20693b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
20703b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
20713b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
20723b294360febd89e3383143af086efe2014571afaRafael Espindola  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
2073006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  StringRef Str;
207408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  const StringLiteral *SE =
2075006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
2076006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  if (SE)
2077006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    Str = SE->getString();
20783b294360febd89e3383143af086efe2014571afaRafael Espindola
2079599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(D, Attr.getRange(),
2080599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Platform,
2081599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Introduced.Version,
2082599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Deprecated.Version,
2083599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Obsoleted.Version,
2084599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      IsUnavailable, Str);
2085599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
2086599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
208798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola}
208898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
2089599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaVisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
2090599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                          VisibilityAttr::VisibilityType Vis) {
2091dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola  if (isa<TypedefNameDecl>(D)) {
2092dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "visibility";
2093599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return NULL;
2094dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola  }
209598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VisibilityAttr *ExistingAttr = D->getAttr<VisibilityAttr>();
209698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  if (ExistingAttr) {
209798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    VisibilityAttr::VisibilityType ExistingVis = ExistingAttr->getVisibility();
209898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    if (ExistingVis == Vis)
2099599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola      return NULL;
210098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    Diag(ExistingAttr->getLocation(), diag::err_mismatched_visibility);
210198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    Diag(Range.getBegin(), diag::note_previous_attribute);
210298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    D->dropAttr<VisibilityAttr>();
210398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  }
2104599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return ::new (Context) VisibilityAttr(Range, Context, Vis);
21050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
21060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
21071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
21091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
21106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2111bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21127a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
21136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
21146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2115bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21165cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
2117fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
21183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
21196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2121bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
2123cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
2124bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2125c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
2126cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
2127c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
2128cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
2129c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
2130cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
21314188760f6bb20f91c6883dffd89204419f852deeJohn McCall  else if (TypeStr == "protected") {
21324188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // Complain about attempts to use protected visibility on targets
21334188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // (like Darwin) that don't support it.
21344188760f6bb20f91c6883dffd89204419f852deeJohn McCall    if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
21354188760f6bb20f91c6883dffd89204419f852deeJohn McCall      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
21364188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Default;
21374188760f6bb20f91c6883dffd89204419f852deeJohn McCall    } else {
21384188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Protected;
21394188760f6bb20f91c6883dffd89204419f852deeJohn McCall    }
21404188760f6bb20f91c6883dffd89204419f852deeJohn McCall  } else {
214108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
21426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2145599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type);
2146599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
2147599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
21486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
21496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
21511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
2152d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
2153d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
215487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
2155883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
2156d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
2157d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
2158d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
215987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
216087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
216187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2162d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
2163d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
216487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2165d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
216687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2167d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
2168d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
2169d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
21705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
2171d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
2172d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
2173d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
2174d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
2175d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
2176d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
2177d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
2178d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
2179d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
2180d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
2181d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
2182d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
2183d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
2184d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
2185d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
2186d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
218787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
2188d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
2189d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
2190d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
219108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  if (family == ObjCMethodFamilyAttr::OMF_init &&
2192f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
2193f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
2194f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
2195f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
2196f85e193739c953358c865005855253af4f68a497John McCall    return;
2197f85e193739c953358c865005855253af4f68a497John McCall  }
2198f85e193739c953358c865005855253af4f68a497John McCall
2199768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
2200f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
2201d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
2202d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
22031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
22041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
22051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
22060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
2207bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22080db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
22090db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
22100db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
22110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
22120db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
2213bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2214768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
22150db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
22160db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
22171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
2218fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
22192b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2220fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
2221fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
2222162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2223fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
2224fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
22256217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
2226fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2227fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
2228fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
2229fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
22303427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
22313427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian    QualType T = PD->getType();
22323427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian    if (!T->isPointerType() ||
22333427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
22343427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian      S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
22353427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian      return;
22363427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian    }
22373427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian  }
22383427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian  else {
2239f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // It is okay to include this attribute on properties, e.g.:
2240f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
2241f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2242f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
2243f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // In this case it follows tradition and suppresses an error in the above
224408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    // case.
22459b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
2246f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  }
2247768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
2248fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
2249fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
2250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
22511b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2252f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
22532b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2254f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
2255f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
2256f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
2257f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
2258f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
2259f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
2260f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
2261f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
2262768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
2263f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
2264f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
22651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2266bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2267fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
22683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
22699eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
22709eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2271bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
22733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
22749eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
22759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2276bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2277cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
227892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
22799eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
22809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
2281fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
22823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
22839eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
22849eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2285bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2286768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
22879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
22889eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
22891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2290770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
2291770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
2292bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
2293770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
2294bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2295bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22963323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
2297770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
22987a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
2299770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
2300ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2301ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
2302fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
2304770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2305770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2306bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23073323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
2308fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2309fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
2310770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2311770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
23123323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
23133323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
2314770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2315770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
23163323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
2317770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
23187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
2319770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
2320ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2321ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
2322fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
2324770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2325770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2326770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
2327bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23283323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
2329770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
2330770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
2331fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2332fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
2333770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2334770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2335770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2336770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
233787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
23383323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
2339897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
2340897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
2341897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
2342897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
2343bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2344897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
23453bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2346770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2347bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
234887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
2349770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
23503bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2351770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
23522f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
2353a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
2354a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    if (!BD->isVariadic()) {
2355a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2356a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      return;
2357a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    }
235887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
23592f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
2360daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
236187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
2362f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
23632f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
23643bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
23653bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
23662f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
23672f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
2368ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
23692f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2370883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
23712f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
23722f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
2373770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
2374fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2375883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
2376770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
2377770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2378768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
2379f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
2380770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
2381770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
23821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
2383026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
23841731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2385026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
2386026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
2387f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
2388026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2389883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
2390026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
2391026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
2392bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2393f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
2394f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2395f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
2396f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
2397f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
2398f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2399f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
2400f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2401f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
2402f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
2403f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
240408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
2405768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
2406026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
2407026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
24081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
241087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
241187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
24126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
241587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
241613c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    if (isa<CXXRecordDecl>(D)) {
241713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
241813c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      return;
241913c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    }
242087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
242187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
2422f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
2423f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
2424f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
242587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
2426332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
2427332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
2428332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
242987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
24306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
24316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
2432bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2433768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
24346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
24381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
24396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
24401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
24416e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
24426e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
24436e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
24440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
24450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
24460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
24470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
24480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
2449def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2450bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
245190eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2452def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
2453def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
2454c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2455883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
24566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
24576e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
24586e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
24596e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
2460768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
24616e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
24626e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
24630df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner// Handles reqd_work_group_size and work_group_size_hint.
24640df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattnerstatic void handleWorkGroupSize(Sema &S, Decl *D,
24654ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky                                const AttributeList &Attr) {
246608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  assert(Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize
24670df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      || Attr.getKind() == AttributeList::AT_WorkGroupSizeHint);
24680df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner
24696f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
24700df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  if (!checkAttributeNumArgs(S, Attr, 3)) return;
24716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
24726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
24736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
24747a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
24756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
2476ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2477ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
24786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
24790df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner        << Attr.getName()->getName() << E->getSourceRange();
24806f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
24816f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
24826f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
24836f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
24840df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner
24850df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize
24860df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner    && D->hasAttr<ReqdWorkGroupSizeAttr>()) {
24870df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      ReqdWorkGroupSizeAttr *A = D->getAttr<ReqdWorkGroupSizeAttr>();
24880df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      if (!(A->getXDim() == WGSize[0] &&
24890df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner            A->getYDim() == WGSize[1] &&
24900df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner            A->getZDim() == WGSize[2])) {
24910df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner        S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
24920df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner          Attr.getName();
24930df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      }
24940df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  }
24950df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner
24960df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  if (Attr.getKind() == AttributeList::AT_WorkGroupSizeHint
24970df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner    && D->hasAttr<WorkGroupSizeHintAttr>()) {
24980df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      WorkGroupSizeHintAttr *A = D->getAttr<WorkGroupSizeHintAttr>();
24990df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      if (!(A->getXDim() == WGSize[0] &&
25000df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner            A->getYDim() == WGSize[1] &&
25010df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner            A->getZDim() == WGSize[2])) {
25020df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner        S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
25030df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner          Attr.getName();
25040df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      }
25050df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  }
25060df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner
25070df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize)
25080df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner    D->addAttr(::new (S.Context)
25090df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner                 ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
25100df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner                                       WGSize[0], WGSize[1], WGSize[2]));
25110df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  else
25120df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner    D->addAttr(::new (S.Context)
25130df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner                 WorkGroupSizeHintAttr(Attr.getRange(), S.Context,
25140df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner                                       WGSize[0], WGSize[1], WGSize[2]));
25156f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
25166f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
2517599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaSectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
2518599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                    StringRef Name) {
2519420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola  if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
2520420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola    if (ExistingAttr->getName() == Name)
2521599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola      return NULL;
2522420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola    Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section);
2523420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola    Diag(Range.getBegin(), diag::note_previous_attribute);
2524599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return NULL;
2525420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola  }
2526599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return ::new (Context) SectionAttr(Range, Context, Name);
25276f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
25286f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
25291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
253017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
25311731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
253217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
253317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
253417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
253517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
25367a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2537797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
253817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
2539797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
254017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
254117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
25421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2543797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
2544bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2545a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2546a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2547a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2548797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2549797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
25501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2551a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2552a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2553a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2554a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2555a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2556599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(),
2557599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                            SE->getString());
2558599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
2559599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
256017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
256117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
25626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2565831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
25663c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
25676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
256908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
257087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2571b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2572ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2573b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2574768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2575b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
25766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2579232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2580831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
25813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2582232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2583232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2584bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
258587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2586b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2587ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2588b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2589768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2590b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2591232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2592232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
25931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2594232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
25951731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2596232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2597bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2598768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2599232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2600232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
26011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2602bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2603f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2604f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2605f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2606bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2607f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2608f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2609f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2610f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2611bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
261287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2613bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2614f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2615f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2616f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2617f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2618bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2619f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2620c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2621f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2622f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2623f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2624f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2625f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2626f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2627f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2628f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2629bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2630f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2631f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2632f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2633f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2634f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2635f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2636f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2637f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2638f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2639f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2640f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2641f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2642f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2643f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2644bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
264589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
264689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
264789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
264889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2649b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2650b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2651f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
265289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
265389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
265489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
265589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2656bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2657768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
26585f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
2659f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2660f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2661bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2662bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
26631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
26641731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
26655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
26661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
266787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
26685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2669883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
26705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
26715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
267207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
267307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
267407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
267587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
267687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
26775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
267807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
26795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
26807a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
26815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2682ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2683ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
26845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
26855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
26865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
26875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2688bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
26895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
26905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
26915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
26925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
26935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2694bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
26955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2696bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
269707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
269807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
269907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
270007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
270107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
270207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
270307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
270407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
270507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
27065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
270787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2708bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
27095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
27105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
27115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
27125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
27136217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
27145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
27155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2716bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
27175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
27185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2719bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
272087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
27215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
27225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
27235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
27246217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
27255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
27265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2727bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
27285b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
27295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2730bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2731bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2732768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
273307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
27345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
27355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
27362b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
27372b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
27382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
27392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
27402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
27413c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
27422b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
27432b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
27442b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
27452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
27462b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
27475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
2748c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer  return llvm::StringSwitch<FormatAttrKind>(Format)
2749c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    // Check for formats that get handled specially.
2750c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("NSString", NSStringFormat)
2751c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("CFString", CFStringFormat)
2752c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("strftime", StrftimeFormat)
2753c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer
2754c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    // Otherwise, check for supported formats.
2755c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
2756c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
2757c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("kprintf", SupportedFormat) // OpenBSD.
2758c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer
2759c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
2760c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Default(InvalidFormat);
27612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
27622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2763521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2764521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
27651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
27661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
27674e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!S.getLangOpts().CPlusPlus) {
2768521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2769521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2770521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
277108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
277287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2773b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2774b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2775b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2776b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
277787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2778b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2779b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2780b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2781b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2782b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2783b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2784b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
278508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
2786521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2787521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2788521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2789521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2790521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
27917a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
279208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
2793521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2794521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2795521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2796521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2797521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2798521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2799521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2800521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
28019f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2802521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2803521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2804521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2805521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2806521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2807521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2808768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2809f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2810521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2811521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2812599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaFormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
2813599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                  int FormatIdx, int FirstArg) {
2814bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola  // Check whether we already have an equivalent format attribute.
2815bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola  for (specific_attr_iterator<FormatAttr>
2816bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola         i = D->specific_attr_begin<FormatAttr>(),
2817bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola         e = D->specific_attr_end<FormatAttr>();
2818bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola       i != e ; ++i) {
2819bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola    FormatAttr *f = *i;
2820bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola    if (f->getType() == Format &&
2821bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola        f->getFormatIdx() == FormatIdx &&
2822bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola        f->getFirstArg() == FirstArg) {
2823bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola      // If we don't have a valid location for this attribute, adopt the
2824bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola      // location.
2825bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola      if (f->getLocation().isInvalid())
2826bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola        f->setRange(Range);
2827599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola      return NULL;
2828bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola    }
2829bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola  }
2830bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola
2831599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
2832599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                    FirstArg);
2833bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola}
2834bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola
2835bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2836bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
28371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
28386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2839545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2840fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
28413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
28426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
28446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2845545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
28463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
28476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
28496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
285087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2851fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2852883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
28556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
285607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
285707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
285887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
285987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
28606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
28616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
28636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
28652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
28662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
28672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
28682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
28692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
287008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
28713c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
28723c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
287308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
28742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2875fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
287601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
28776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
28796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
28817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2882803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2883ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2884ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2885fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
28863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
28876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
28896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2891fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
28923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
28936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
28956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
28976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2898bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
28994a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
29004a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
290107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
290207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
290307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
29044a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
29054a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
29064a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
29074a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
29081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
29096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
291087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
29116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2913085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2914fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2915fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2916085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2917085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
29182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2919390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2920390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2921803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2922390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2923fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2924fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
29256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2926bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
29276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
29286217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2929390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2930fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2931fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
29326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
29367a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2937803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2938ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2939ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2940fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
29413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
29426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
29466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
294787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
29486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
29496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
295087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
29516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
29526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
29536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
29563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
29572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
29586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2959fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2960fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
29616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
29626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
29636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
29646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2965fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
29663c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
29676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2970599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format,
2971cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
2972599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                          FirstArg.getZExtValue());
2973599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
2974599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
29756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
29766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
29781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
29796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
29801731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
29816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29821731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
29836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
29850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
298687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
29870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
29880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
29890c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
299087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
29910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
29920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2993fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2994883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
29956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29985e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall  if (!RD->isCompleteDefinition()) {
2999bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
30000c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
30010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
30020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
30030c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
300417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
300517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
30060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
30070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
30080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
30090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
3010bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
30110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
30120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
301390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
3014bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
301590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
301690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
30170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
30180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
3019bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
30200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
30210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
30220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
30230c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
30240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
30250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
30260c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
30270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
3028bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
30290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
3030bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
30310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
30320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
30330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
3034bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
30350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
30360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
3037bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
3038bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
3039bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
30406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3041768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
30426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
30436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
30441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
30456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
30461731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
30476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
30481731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
30497a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
3050797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
3051bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
30526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
30536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
30546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
3055797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
30566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
30576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
305877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
305977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
306077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
306177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
306277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
306377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
306477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
306577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
3066768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
3067f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
30686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
30696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
30701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
30716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
3072545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
30733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
30746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
30756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3076fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman
3077bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
3078bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
3079bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
30806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3081545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
308208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
3083fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman               true, 0, Attr.isDeclspecAttribute()));
30844ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
30854ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
30864ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
308708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0),
3088fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                   Attr.isDeclspecAttribute());
30894ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
30904ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
309108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaovoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
3092fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                          bool isDeclSpec) {
30930b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  // FIXME: Handle pack-expansions here.
30940b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  if (DiagnoseUnexpandedParameterPack(E))
30950b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne    return;
30960b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne
30974ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
30984ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
309908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E,
3100fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                                           isDeclSpec));
31016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
31026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3103bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3104768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
3105cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
310649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
3107ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor  ExprResult ICE
3108ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor    = VerifyIntegerConstantExpression(E, &Alignment,
3109ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor        diag::err_aligned_attribute_argument_not_int,
3110ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor        /*AllowFold*/ false);
3111282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  if (ICE.isInvalid())
311249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
3113396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
31144ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
31154ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
3116396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
3117396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
3118fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman  if (isDeclSpec) {
3119fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman    // We've already verified it's a power of 2, now let's make sure it's
3120fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman    // 8192 or less.
3121fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman    if (Alignment.getZExtValue() > 8192) {
312208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao      Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192)
3123fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman        << E->getSourceRange();
3124fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman      return;
3125fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman    }
3126fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman  }
3127396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
312808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take(),
3129fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                                         isDeclSpec));
3130cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
3131cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
313208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaovoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
3133fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                          bool isDeclSpec) {
3134cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
3135cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
313608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS,
3137fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                                         isDeclSpec));
3138cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
31396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3140fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3141d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
3142bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
3143fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
3144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
3145bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
3146bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
31471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3148fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
3149fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
3150fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3151fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
31521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
3153fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
31541731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3155fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3156fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
3157fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
31580b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
3159fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3160fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3161210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
31625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
3163fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3164fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
3165210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
3166210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
3167fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3168fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
3169fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
317073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
3171210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
3172fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
317373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
317473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
317573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
317673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
317773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
317873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
317973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
318073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
318173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
318273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
318373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
318473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
318573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
318673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
318773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
318873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
3189fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3190fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
3191fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
3192fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
3193210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
3194bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3195210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
3196bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
3197fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3198fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
3199210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
3200bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3201fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3202fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3203fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3204fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
3205162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
3206fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
3207fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
3208fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
3209fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
3210fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
3211768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
3212fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3213fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
321473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
3215183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
321673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
321773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
32182ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
321973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
322073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
322173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
322273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
322373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
322473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
322573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
322673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
322773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
3228390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
3229390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
3230390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
3231390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
3232f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
3233f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
3234fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
3235fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
3236fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
32373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
3238fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3239fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
32403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3241fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3242fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
324373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
324473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
324573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
324673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
3247fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
32480b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
3249fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
32500b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
3251fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3252fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
325373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
325473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
325573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
325673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
3257fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
32580b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
3259fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
32600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
3261fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3262fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
3263fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
32640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
3265fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
32660b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
3267fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
32680b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
3269fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3270fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
3271fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
32720b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
3273fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
3274bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
3275aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
3276aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
3277aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
3278fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
3279bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
3280aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
3281aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
3282aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
3283fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
328473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
328573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
328673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
3287f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
3288f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
3289f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3290f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
3291f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
3292f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
3293f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
3294f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
3295f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
329673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
3297fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3298fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
329973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
330073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
3301fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3302fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3303fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
3304162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
3305ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
3306a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
3307ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
3308fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
3309fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
33100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
33111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3312d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
33131731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
3314d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
3315e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
331678d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
331778d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky    if (!VD->hasGlobalStorage())
331878d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky      S.Diag(Attr.getLoc(),
331978d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky             diag::warn_attribute_requires_functions_or_static_globals)
332078d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky        << Attr.getName();
332178d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky  } else if (!isFunctionOrMethod(D)) {
332278d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky    S.Diag(Attr.getLoc(),
332378d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky           diag::warn_attribute_requires_functions_or_static_globals)
332478d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky      << Attr.getName();
3325d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
3326d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
3327bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3328768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
3329d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
3330d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
33311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
33325bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
33331731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
33345bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
33351731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3336bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
333787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
33385bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3339883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
33405bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
33415bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
3342bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3343768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
33445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
33455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
33461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
33471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
33487255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
33491731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
33507255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
33511731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
33527255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
335387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
33547255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3355883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
33567255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
33577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
33587255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
3359768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
3360f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
33617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
33627255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
33630557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hinesstatic void handleKernelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
33640557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines  if (S.LangOpts.Renderscript) {
33650557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines    D->addAttr(::new (S.Context) KernelAttr(Attr.getRange(), S.Context));
33660557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines  } else {
33670557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "kernel";
33680557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines  }
33690557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines}
33700557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines
33711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3372ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3373ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
3374831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
3375ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3376ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3377ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3378ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
337987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
3380ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3381883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
3382ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3383ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3384ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3385768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
3386ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3387ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
3388ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3389ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3390ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
33911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3392ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3393ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
3394ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
3395ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3396ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3397ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3398ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
339987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
3400ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3401883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
3402ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3403ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3404ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3405768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
3406ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3407ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
3408ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3409ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3410ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
34111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3412ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3413ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
34141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3415ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3416ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
341787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
3418ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3419883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
3420ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3421ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3422ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
342387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
34242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
3425723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
34262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
34272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
34282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
34292c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
34302c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
34312c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
34322c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
34332c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
34342c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
34352c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
34362c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
34372c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
3438768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
3439ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3440ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
3441ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3442ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3443ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
34441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3445ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3446ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
34471731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3448ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
34491731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3450ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
345187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
3452ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3453883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
3454ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3455ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3456ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3457768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
3458ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3459ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
3460ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3461ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3462ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
34631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3464ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3465ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
34661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3467ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
34681731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3469ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
347087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
3471ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3472883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
3473ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3474ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3475ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3476768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
3477ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3478ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
3479ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3480ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3481ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
34821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
348326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
34841731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
348526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
3486bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
348787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
3488c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
348926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3490883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
349126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
349226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
3493bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
34940130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
3495cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
3496c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
3497c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
3498bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3499768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
350026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
350126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
35021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
350387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3504711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
350587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
3506e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3507711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
350887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
3509711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3510e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
351187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
351287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
351387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3514711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3515711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3516711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
351787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
35188e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_FastCall:
3519768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
3520e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
35218e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_StdCall:
3522768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
3523e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
35248e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ThisCall:
3525768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
352604633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
35278e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CDecl:
3528768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
3529e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
35308e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pascal:
3531768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
353252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
35338e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pcs: {
353487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
3535414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
35365cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
353787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3538414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
353987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3540414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3541414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3542414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
35435f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3544414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
3545414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
3546414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
3547414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
3548414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
3549414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
355087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
355187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3552414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3553414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3554414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
3555768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
3556414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3557e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
3558e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
3559e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
3560e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
3561e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
35621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
356356aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
3564768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3565f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
3566f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
3567711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
3568711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
3569711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3570711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3571831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
35728e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt      !(attr.getKind() == AttributeList::AT_Pcs && attr.getNumArgs() == 1)) ||
3573831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
3574711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3575711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
3576711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3577ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
357855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3579414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3580414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3581711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
35828e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CDecl: CC = CC_C; break;
35838e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
35848e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;
35858e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;
35868e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pascal: CC = CC_X86Pascal; break;
35878e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pcs: {
3588414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3589414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
35905cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3591414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3592414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3593414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3594414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3595414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3596414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
35975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3598414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3599414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3600414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3601414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3602414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3603414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3604414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3605414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3606414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
36077530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("unexpected attribute kind");
3608711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3609711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3610711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3611711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3612711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
36131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
361487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3615711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3616711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
361787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3618711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3619711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
362087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
362187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
362287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3623ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3624ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
362555d3aaf9a537888734762170823daf750ea9036dEli Friedman
3626768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3627711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3628711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3629711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3630711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
363187c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
363287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3633711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3634711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
363587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
363687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
363787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3638711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3639711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3640711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
364187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
364255d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3643ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3644711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
364587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
364655d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
364787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3648711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
364955d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
365055d3aaf9a537888734762170823daf750ea9036dEli Friedman
3651bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
365287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
365355d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
365487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3655711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
365655d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
365755d3aaf9a537888734762170823daf750ea9036dEli Friedman
3658711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3659bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
366087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3661bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
366287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3663711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
366455d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
366555d3aaf9a537888734762170823daf750ea9036dEli Friedman
3666711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3667ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3668ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
36691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
36707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
36717b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
36727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3673bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3674bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
36757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
36767b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
36777b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
367887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
36797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3680883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
36817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
36827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
36837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
36847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
36857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
36867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
36877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
36887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
36897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
36907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
36917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
36927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
36937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
36947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
36957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
36967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
36977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
36987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
36997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
37007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
37017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
37027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
37037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
37047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
37057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3706768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
37077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
37087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
37097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
37107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
37117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
37127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
37137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
37140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3715b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3716b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3717b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3718c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
371908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  return type->isDependentType() ||
372008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao         type->isObjCObjectPointerType() ||
37216c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         S.Context.isObjCNSObjectType(type);
3722c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3723c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
372408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  return type->isDependentType() ||
372508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao         type->isPointerType() ||
37266c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         isValidSubjectOfNSAttribute(S, type);
3727c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3728c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
37291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
373087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3731c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
373287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3733768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3734c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3735c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3736c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3737c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
37388e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  if (Attr.getKind() == AttributeList::AT_NSConsumed) {
3739c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3740c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3741c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3742c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3743c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3744c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3745c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3746c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
374787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3748768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3749c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3750c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3751c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3752c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3753768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3754c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3755768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3756c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3757c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
37581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
37591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
376087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
376187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3762768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3763c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3764c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3765c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3766768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3767c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3768c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
37691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
37701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3771b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3772c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3773bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
377487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3775c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
377687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3777831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
37784e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
37798e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt           (Attr.getKind() == AttributeList::AT_NSReturnsRetained))
3780f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
378187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3782c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
37835dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
378487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3785768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3786883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3787b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3788b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3789bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3790c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3791c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
379287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
37937530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("invalid ownership attribute");
37948e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsAutoreleased:
37958e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsRetained:
37968e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsNotRetained:
3797c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3798c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3799c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3800c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
38018e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFReturnsRetained:
38028e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFReturnsNotRetained:
3803c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3804c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3805c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3806c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3807c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3808c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
380987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3810768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3811bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
38125dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3813bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
381487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3815b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3816b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
38178e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_NSReturnsAutoreleased:
3818768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3819c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3820c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
38218e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_CFReturnsNotRetained:
3822768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3823f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
382431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
38258e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_NSReturnsNotRetained:
3826768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3827f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
382831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
38298e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_CFReturnsRetained:
3830768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3831f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3832b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
38338e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_NSReturnsRetained:
3834768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3835f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3836b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3837b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3838b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3839b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3840dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3841dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3842dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3843dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3844dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3845dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
384694d55d7ecdd693788a8f3910a0da1b5ecdaa8a86Fariborz Jahanian  if (!method) {
38470e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3848f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
3849dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3850dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3851dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3852dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3853dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
385408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
3855f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3856f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3857dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3858dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3859dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3860dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3861dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3862dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3863dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3864dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3865dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3866768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3867dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3868dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
38698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
38708dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
38718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
38728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3873f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << A.getRange() << A.getName() << ExpectedFunction;
38748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
38758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
38768dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
38778e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  bool IsAudited = (A.getKind() == AttributeList::AT_CFAuditedTransfer);
38788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
38798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
38808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
38818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
38828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
38838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
38848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
38858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
38868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
38878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
38888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
38898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
38908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
38918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
38928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
38938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
38948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
38958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
38968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
38978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
38988dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
38998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
39008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
39018dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
39028dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
39038dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3904fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
3905fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
3906fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
3907fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
3908fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3909f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedStruct;
3910fe98da0fa352462c02db037360788748f95466f7John McCall  }
3911fe98da0fa352462c02db037360788748f95466f7John McCall
3912fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
3913fe98da0fa352462c02db037360788748f95466f7John McCall
3914fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
3915fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
3916fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
39174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (ParmName && S.getLangOpts().ObjC1) {
3918fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
3919fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
3920fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
3921fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
3922fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
3923fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
3924fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
3925fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
3926fe98da0fa352462c02db037360788748f95466f7John McCall      }
3927fe98da0fa352462c02db037360788748f95466f7John McCall    }
3928fe98da0fa352462c02db037360788748f95466f7John McCall  }
3929fe98da0fa352462c02db037360788748f95466f7John McCall
3930fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
3931fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
3932fe98da0fa352462c02db037360788748f95466f7John McCall}
3933fe98da0fa352462c02db037360788748f95466f7John McCall
39341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
39351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
393687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3937f85e193739c953358c865005855253af4f68a497John McCall
393887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3939f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    << Attr.getRange() << Attr.getName() << ExpectedVariable;
3940f85e193739c953358c865005855253af4f68a497John McCall}
3941f85e193739c953358c865005855253af4f68a497John McCall
39421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
39431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
394487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
394587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3946f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedVariable;
3947f85e193739c953358c865005855253af4f68a497John McCall    return;
3948f85e193739c953358c865005855253af4f68a497John McCall  }
3949f85e193739c953358c865005855253af4f68a497John McCall
395087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3951f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3952f85e193739c953358c865005855253af4f68a497John McCall
3953f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3954f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
395587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3956f85e193739c953358c865005855253af4f68a497John McCall      << type;
3957f85e193739c953358c865005855253af4f68a497John McCall    return;
3958f85e193739c953358c865005855253af4f68a497John McCall  }
3959f85e193739c953358c865005855253af4f68a497John McCall
3960f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3961f85e193739c953358c865005855253af4f68a497John McCall
3962f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3963f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3964f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3965f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3966f85e193739c953358c865005855253af4f68a497John McCall
3967f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3968f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3969f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3970f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3971f85e193739c953358c865005855253af4f68a497John McCall    break;
3972f85e193739c953358c865005855253af4f68a497John McCall
3973f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3974f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3975f85e193739c953358c865005855253af4f68a497John McCall    break;
3976f85e193739c953358c865005855253af4f68a497John McCall
3977f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3978f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
397987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3980f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3981f85e193739c953358c865005855253af4f68a497John McCall    break;
3982f85e193739c953358c865005855253af4f68a497John McCall  }
3983f85e193739c953358c865005855253af4f68a497John McCall
398487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3985768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3986f85e193739c953358c865005855253af4f68a497John McCall}
3987f85e193739c953358c865005855253af4f68a497John McCall
398811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
398911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
399011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
399111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
39921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
399362ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
399411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
39951731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
399611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
39971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
399811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
399911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
40005cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
4001d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
4002d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
4003d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
4004d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
4005d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
40065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
4007d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
4008d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
4009d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
4010f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
4011d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
4012d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
4013d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4014d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
4015d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
4016d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
4017d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4018d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
4019d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
4020d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
4021f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
4022d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
40235f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
4024f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
4025f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
4026f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
4027f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
4028d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
4029d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
4030d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4031d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
4032d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
4033d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
4034d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4035d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
4036d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
4037d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
4038d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
403911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
4040768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
404111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
4042d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
404311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
4044f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
4045f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
4046c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallstatic void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4047c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  if (S.LangOpts.MicrosoftExt) {
4048c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    AttributeList::Kind Kind = Attr.getKind();
40498e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    if (Kind == AttributeList::AT_SingleInheritance)
4050c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4051c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context));
40528e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    else if (Kind == AttributeList::AT_MultipleInheritance)
4053c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4054c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context));
40558e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    else if (Kind == AttributeList::AT_VirtualInheritance)
4056c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4057c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context));
4058c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  } else
4059c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4060c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall}
4061c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
4062c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallstatic void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4063c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  if (S.LangOpts.MicrosoftExt) {
4064c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    AttributeList::Kind Kind = Attr.getKind();
40658e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    if (Kind == AttributeList::AT_Ptr32)
4066c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4067c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context));
40688e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    else if (Kind == AttributeList::AT_Ptr64)
4069c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4070c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context));
40718e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    else if (Kind == AttributeList::AT_Win64)
4072c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4073c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) Win64Attr(Attr.getRange(), S.Context));
4074c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  } else
4075c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4076c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall}
4077c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
4078adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencerstatic void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4079adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer  if (S.LangOpts.MicrosoftExt)
4080adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    D->addAttr(::new (S.Context) ForceInlineAttr(Attr.getRange(), S.Context));
4081adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer  else
4082adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4083adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer}
4084adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer
4085b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
40860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
40870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
40880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
40891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
40901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
409160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
40928e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDADevice:  handleDeviceAttr      (S, D, Attr); break;
40938e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDAHost:    handleHostAttr        (S, D, Attr); break;
40948e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Overloadable:handleOverloadableAttr(S, D, Attr); break;
40950557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines  case AttributeList::AT_kernel:      handleKernelAttr      (S, D, Attr); break;
409660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
409760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
409860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
409960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
4100e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
41011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
41021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
4103803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
41048e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_IBAction:          handleIBAction(S, D, Attr); break;
41058e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
41068e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_IBOutletCollection:
41071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
41088e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AddressSpace:
41098e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_OpenCLImageAccess:
41108e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCGC:
41118e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_VectorSize:
41128e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NeonVectorType:
41138e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NeonPolyVectorType:
4114bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
4115bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
4116803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
41178e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDADevice:
41188e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDAHost:
41198e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Overloadable:
412008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  case AttributeList::AT_Kernel:
412160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
412260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
412360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
41248e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Alias:       handleAliasAttr       (S, D, Attr); break;
41258e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Aligned:     handleAlignedAttr     (S, D, Attr); break;
41268e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AllocSize:   handleAllocSizeAttr   (S, D, Attr); break;
41278e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AlwaysInline:
41281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
41298e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AnalyzerNoReturn:
41301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
41315e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  case AttributeList::AT_TLSModel:    handleTLSModelAttr    (S, D, Attr); break;
41328e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Annotate:    handleAnnotateAttr    (S, D, Attr); break;
41338e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break;
41348e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CarriesDependency:
41351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
41368e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Common:      handleCommonAttr      (S, D, Attr); break;
41378e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDAConstant:handleConstantAttr    (S, D, Attr); break;
41388e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Constructor: handleConstructorAttr (S, D, Attr); break;
41398e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Deprecated:
4140bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    handleAttrWithMessage<DeprecatedAttr>(S, D, Attr, "deprecated");
4141bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    break;
41428e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Destructor:  handleDestructorAttr  (S, D, Attr); break;
41438e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ExtVectorType:
41441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
41453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
41468e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Format:      handleFormatAttr      (S, D, Attr); break;
41478e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_FormatArg:   handleFormatArgAttr   (S, D, Attr); break;
41488e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDAGlobal:  handleGlobalAttr      (S, D, Attr); break;
41498e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_GNUInline:   handleGNUInlineAttr   (S, D, Attr); break;
41508e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDALaunchBounds:
41511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
41527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
41538e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Mode:        handleModeAttr        (S, D, Attr); break;
41548e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Malloc:      handleMallocAttr      (S, D, Attr); break;
41558e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_MayAlias:    handleMayAliasAttr    (S, D, Attr); break;
41568e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoCommon:    handleNoCommonAttr    (S, D, Attr); break;
41578e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NonNull:     handleNonNullAttr     (S, D, Attr); break;
4158dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
4159dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
4160dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
41611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
41628e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Cold:        handleColdAttr        (S, D, Attr); break;
41638e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Hot:         handleHotAttr         (S, D, Attr); break;
41648e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Naked:       handleNakedAttr       (S, D, Attr); break;
41658e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoReturn:    handleNoReturnAttr    (S, D, Attr); break;
41668e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoThrow:     handleNothrowAttr     (S, D, Attr); break;
41678e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDAShared:  handleSharedAttr      (S, D, Attr); break;
41688e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_VecReturn:   handleVecReturnAttr   (S, D, Attr); break;
41698e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt
41708e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCOwnership:
41711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
41728e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCPreciseLifetime:
41731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
4174f85e193739c953358c865005855253af4f68a497John McCall
41758e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCReturnsInnerPointer:
4176dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
4177dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
41788e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSBridged:
4179fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
4180fe98da0fa352462c02db037360788748f95466f7John McCall
41818e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFAuditedTransfer:
41828e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFUnknownTransfer:
41838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
41848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
4185b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
41868e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFConsumed:
41878e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSConsumed:  handleNSConsumedAttr  (S, D, Attr); break;
41888e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSConsumesSelf:
41891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
4190c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
41918e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsAutoreleased:
41928e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsNotRetained:
41938e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFReturnsNotRetained:
41948e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsRetained:
41958e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFReturnsRetained:
41961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
4197b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
41980df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  case AttributeList::AT_WorkGroupSizeHint:
41998e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ReqdWorkGroupSize:
42000df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner    handleWorkGroupSize(S, D, Attr); break;
42016f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
420208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  case AttributeList::AT_InitPriority:
42031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
420408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
42058e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Packed:      handlePackedAttr      (S, D, Attr); break;
42068e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Section:     handleSectionAttr     (S, D, Attr); break;
42078e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Unavailable:
4208bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    handleAttrWithMessage<UnavailableAttr>(S, D, Attr, "unavailable");
4209bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    break;
421008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  case AttributeList::AT_ArcWeakrefUnavailable:
421108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    handleArcWeakrefUnavailableAttr (S, D, Attr);
4212742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
42138e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCRootClass:
4214b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    handleObjCRootClassAttr(S, D, Attr);
4215b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    break;
421608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  case AttributeList::AT_ObjCRequiresPropertyDefs:
421708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
4218e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    break;
42198e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Unused:      handleUnusedAttr      (S, D, Attr); break;
42208e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ReturnsTwice:
4221f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
4222f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
42238e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Used:        handleUsedAttr        (S, D, Attr); break;
42248e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Visibility:  handleVisibilityAttr  (S, D, Attr); break;
42258e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr);
4226026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
42278e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Weak:        handleWeakAttr        (S, D, Attr); break;
42288e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_WeakRef:     handleWeakRefAttr     (S, D, Attr); break;
42298e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_WeakImport:  handleWeakImportAttr  (S, D, Attr); break;
42308e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_TransparentUnion:
42311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
4232803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
42338e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCException:
42341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
42350db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
42368e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCMethodFamily:
42371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
4238d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
42398e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCNSObject:handleObjCNSObject    (S, D, Attr); break;
42408e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Blocks:      handleBlocksAttr      (S, D, Attr); break;
42418e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Sentinel:    handleSentinelAttr    (S, D, Attr); break;
42428e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Const:       handleConstAttr       (S, D, Attr); break;
42438e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pure:        handlePureAttr        (S, D, Attr); break;
42448e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Cleanup:     handleCleanupAttr     (S, D, Attr); break;
42458e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoDebug:     handleNoDebugAttr     (S, D, Attr); break;
42468e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoInline:    handleNoInlineAttr    (S, D, Attr); break;
42478e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Regparm:     handleRegparmAttr     (S, D, Attr); break;
4248bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
424905f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
425005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
42518e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoInstrumentFunction:  // Interacts with -pg.
42521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
42537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
42548e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_StdCall:
42558e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CDecl:
42568e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_FastCall:
42578e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ThisCall:
42588e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pascal:
42598e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pcs:
42601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
426104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
42628e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_OpenCLKernel:
42631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
4264f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
4265c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
4266c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  // Microsoft attributes:
42678e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_MsStruct:
4268c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    handleMsStructAttr(S, D, Attr);
4269c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    break;
42708e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Uuid:
42711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
427211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
42738e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_SingleInheritance:
42748e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_MultipleInheritance:
42758e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_VirtualInheritance:
4276c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    handleInheritanceAttr(S, D, Attr);
4277c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    break;
42788e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Win64:
42798e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Ptr32:
42808e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Ptr64:
4281c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    handlePortabilityAttr(S, D, Attr);
4282c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    break;
42838e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ForceInline:
4284adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    handleForceInlineAttr(S, D, Attr);
4285adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    break;
4286fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4287fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
42888e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_GuardedVar:
4289fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
4290fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
42918e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_PtGuardedVar:
4292dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handlePtGuardedVarAttr(S, D, Attr);
4293fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
42948e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ScopedLockable:
4295dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleScopedLockableAttr(S, D, Attr);
4296fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
42978e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoAddressSafetyAnalysis:
429871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    handleNoAddressSafetyAttr(S, D, Attr);
429971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    break;
43008e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoThreadSafetyAnalysis:
4301fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
4302fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
43038e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Lockable:
4304fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
4305fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
43068e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_GuardedBy:
4307db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
4308db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43098e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_PtGuardedBy:
4310dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handlePtGuardedByAttr(S, D, Attr);
4311db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43128e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ExclusiveLockFunction:
4313dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleExclusiveLockFunctionAttr(S, D, Attr);
4314db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43158e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ExclusiveLocksRequired:
4316dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleExclusiveLocksRequiredAttr(S, D, Attr);
4317db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43188e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ExclusiveTrylockFunction:
4319dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleExclusiveTrylockFunctionAttr(S, D, Attr);
4320db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43218e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_LockReturned:
4322db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
4323db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43248e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_LocksExcluded:
4325db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
4326db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43278e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_SharedLockFunction:
4328dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleSharedLockFunctionAttr(S, D, Attr);
4329db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43308e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_SharedLocksRequired:
4331dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleSharedLocksRequiredAttr(S, D, Attr);
4332db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43338e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_SharedTrylockFunction:
4334dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleSharedTrylockFunctionAttr(S, D, Attr);
4335db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43368e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_UnlockFunction:
4337db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
4338db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43398e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AcquiredBefore:
4340dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleAcquiredBeforeAttr(S, D, Attr);
4341db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
43428e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AcquiredAfter:
4343dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleAcquiredAfterAttr(S, D, Attr);
4344db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4345fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4346803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
434782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
434882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
434982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
435008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao      S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ?
435108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao             diag::warn_unhandled_ms_attribute_ignored :
4352fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman             diag::warn_unknown_attribute_ignored) << Attr.getName();
4353803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
4354803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
4355803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
4356803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
435760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
435860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
435960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
436060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
43611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
43621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
436360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
436460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
436560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
436660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
436708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  // Type attributes are still treated as declaration attributes by
436808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  // ParseMicrosoftTypeAttributes and ParseBorlandTypeAttributes.  We don't
436908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  // want to process them, however, because we will simply warn about ignoring
4370fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman  // them.  So instead, we will bail out early.
4371fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman  if (Attr.isMSTypespecAttribute())
437260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
437360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
437460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
43751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
437660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
437760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
43781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
437960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
438060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
4381803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
4382803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
4383f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
438460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
438560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
438611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
43871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
438811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
438911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
439011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
439111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
439211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
439360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
439411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
4395dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
439611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
4397803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
4398803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
4399803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
44005f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access
44015f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier.
44025f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
44035f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          const AttributeList *AttrList) {
44045f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
44058e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    if (l->getKind() == AttributeList::AT_Annotate) {
44065f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      handleAnnotateAttr(*this, ASDecl, *l);
44075f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    } else {
44085f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
44095f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      return true;
44105f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    }
44115f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  }
44125f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
44135f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  return false;
44145f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen}
44155f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
4416e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
4417e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
4418e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
4419e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
4420e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
4421e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
4422e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
4423e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4424e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
4425e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
4426e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
4427e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
4428e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
4429e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
4430e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
4431e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
4432e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
4433e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4434e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
4435e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
4436e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
4437e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
4438e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
4439e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
4440e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
4441e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
4442e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
4443e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4444e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
44451dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// \#pragma weak needs a non-definition decl and source may not have one.
4446900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
4447900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
44487b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
4449e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
4450e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
4451900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
4452900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
4453900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
4454900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
4455900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
4456900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
4457900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
4458900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
4459900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
4460900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
4461900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
4462900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
4463900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
4464900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
4465900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
4466c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
4467900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
4468900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
4469900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
4470900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
4471900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
4472900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
4473900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
4474900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
4475900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
4476900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
4477900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
4478900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
44794278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
4480b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
4481e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
4482e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
4483ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
4484a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
448516573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
448616573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
4487b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
4488b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
4489c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
4490b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
4491e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4492e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
4493e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
4494e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
44951dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
4496e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
44977b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
4498c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
4499c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
4500c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
4501c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
4502900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
4503cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
4504cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
4505cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
4506c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
4507c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
4508c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
4509c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
4510c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
4511c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
4512c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
4513c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
4514cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
4515e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4516e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
4517e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
45180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
45190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
45200744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
452160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
452260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
4523d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
4524d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
452531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
452631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
452731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
452831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
452931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
453031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
453131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
453231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
453331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
453431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
453531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
453631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
4537d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
4538e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
4539e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
4540e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4541e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
45420744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
45437f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
454460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4545bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
45460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
45470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
45480744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
45490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
45500744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
45510744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
455260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4553bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
45540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
45550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
455660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
45570744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
455854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4559f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
4560f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
4561f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
4562f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
4563f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
4564a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
4565a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
4566a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
4567f85e193739c953358c865005855253af4f68a497John McCall    return false;
4568f85e193739c953358c865005855253af4f68a497John McCall
4569f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
4570f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
4571f85e193739c953358c865005855253af4f68a497John McCall}
4572f85e193739c953358c865005855253af4f68a497John McCall
4573f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
4574f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4575f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
4576f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
4577f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
4578f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
4579f85e193739c953358c865005855253af4f68a497John McCall    return;
4580f85e193739c953358c865005855253af4f68a497John McCall  }
45814e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (S.getLangOpts().ObjCAutoRefCount)
4582175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
458348d798ce32447607144db70a484cdb99c1180663Benjamin Kramer      // FIXME: we may want to suppress diagnostics for all
458408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao      // kind of forbidden type messages on unavailable functions.
4585175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
458608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao          diag.getForbiddenTypeDiagnostic() ==
4587175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
4588175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
4589175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
4590175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
4591175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
4592f85e193739c953358c865005855253af4f68a497John McCall
4593f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4594f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4595f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
4596f85e193739c953358c865005855253af4f68a497John McCall}
4597f85e193739c953358c865005855253af4f68a497John McCall
45989257664568bf375b7790131a84d9a4fa30a5b7e3John McCallvoid Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
45999257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  assert(DelayedDiagnostics.getCurrentPool());
460013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
46019257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  DelayedDiagnostics.popWithoutEmitting(state);
46029257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
46039257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // When delaying diagnostics to run in the context of a parsed
46049257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // declaration, we only want to actually emit anything if parsing
46059257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // succeeds.
46069257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  if (!decl) return;
46079257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
46089257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // We emit all the active diagnostics in this pool or any of its
46099257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // parents.  In general, we'll get one pool for the decl spec
46109257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // and a child pool for each declarator; in a decl group like:
46119257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  //   deprecated_typedef foo, *bar, baz();
46129257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // only the declarator pops will be passed decls.  This is correct;
46139257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // we really do need to consider delayed diagnostics from the decl spec
46149257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // for each of the different declarations.
461513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  const DelayedDiagnosticPool *pool = &poppedPool;
46169257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  do {
461713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    for (DelayedDiagnosticPool::pool_iterator
46189257664568bf375b7790131a84d9a4fa30a5b7e3John McCall           i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
46199257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      // This const_cast is a bit lame.  Really, Triggered should be mutable.
46209257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
4621eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
46222f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
46232f514480c448708ec382a684cf5e035d3a827ec8John McCall
4624eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
46252f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
4626e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        // Don't bother giving deprecation diagnostics if the decl is invalid.
4627e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        if (!decl->isInvalidDecl())
46289257664568bf375b7790131a84d9a4fa30a5b7e3John McCall          HandleDelayedDeprecationCheck(diag, decl);
46292f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
46302f514480c448708ec382a684cf5e035d3a827ec8John McCall
46312f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
46329257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        HandleDelayedAccessCheck(diag, decl);
46332f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
4634f85e193739c953358c865005855253af4f68a497John McCall
4635f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
46369257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        handleDelayedForbiddenType(*this, diag, decl);
4637f85e193739c953358c865005855253af4f68a497John McCall        break;
463854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
463954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
46409257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  } while ((pool = pool->getParent()));
46412f514480c448708ec382a684cf5e035d3a827ec8John McCall}
464258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
464313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// Given a set of delayed diagnostics, re-emit them as if they had
464413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// been delayed in the current context instead of in the given pool.
464513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// Essentially, this just moves them to the current pool.
464613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCallvoid Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
464713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
464813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  assert(curPool && "re-emitting in undelayed context not supported");
464913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  curPool->steal(pool);
46502f514480c448708ec382a684cf5e035d3a827ec8John McCall}
46512f514480c448708ec382a684cf5e035d3a827ec8John McCall
46522f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
46532f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
46540a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
46552f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
4656c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    // A category implicitly has the availability of the interface.
4657c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4658c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis      return CatD->getClassInterface()->isDeprecated();
46592f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
46602f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
46612f514480c448708ec382a684cf5e035d3a827ec8John McCall}
46622f514480c448708ec382a684cf5e035d3a827ec8John McCall
46639c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
46642f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
46652f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
46662f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
46672f514480c448708ec382a684cf5e035d3a827ec8John McCall
46682f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4669ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
4670c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
4671ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
4672ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
4673b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  else if (DD.getUnknownObjCClass()) {
467408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    Diag(DD.Loc, diag::warn_deprecated_fwdclass_message)
4675b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian      << DD.getDeprecationDecl()->getDeclName();
4676b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class);
4677b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  }
4678c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
4679c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
4680ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
468154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
468254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
46835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
46848e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
468589ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
468654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4687eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
468808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
4689b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              UnknownObjCClass,
4690b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              Message));
469154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
469254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
469354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
469454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
46953a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
469654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4697d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian  if (!Message.empty()) {
469808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
4699c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
470008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    Diag(D->getLocation(),
470108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao         isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
4702d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian                                : diag::note_previous_decl) << D->getDeclName();
4703d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian  }
47048e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
4705350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian    if (!UnknownObjCClass) {
47068e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
470708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao      Diag(D->getLocation(),
470808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
4709350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian                                  : diag::note_previous_decl) << D->getDeclName();
4710350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian    }
471189ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
47128e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
471389ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
471489ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
47158e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
471654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4717