SemaDeclAttr.cpp revision 9257664568bf375b7790131a84d9a4fa30a5b7e3
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,
46f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor  ExpectedStruct
47883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall};
48883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall
49e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
52e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
5387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D,
54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
5687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
6087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
64bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
666217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
67755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
686217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
69d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
70183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
76d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
77a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
7887c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) {
7987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return getFunctionType(D, false) != NULL;
80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
82a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
84d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
8587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) {
8687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isFunction(D)|| isa<ObjCMethodDecl>(D);
87d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
9287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
9387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isFunctionOrMethod(D))
94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
9687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
10087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<BlockDecl>(D);
101620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
102620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
104711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
10587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) {
106f85e193739c953358c865005855253af4f68a497John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
10787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
10887c44604325578b8de07d768391c1c9432404f5aChandler Carruth         isa<ObjCPropertyDecl>(D);
109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
110711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
111d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
112d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
113620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
11487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) {
11587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
11672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
117620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
11887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
119d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
1213568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
123d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
125d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
12687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) {
12787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
12872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
12987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
130d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
13187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_size();
1323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1333568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
13587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
13672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
13787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
138d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
139bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
1413568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1423568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
14387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) {
14487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
1455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
14687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->getResultType();
1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
14987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) {
15087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D)) {
15172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
15387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
154db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
155d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
15687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    return cast<ObjCMethodDecl>(D)->isVariadic();
1573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
16087c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) {
16187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
16207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
16507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
167183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
168b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
171506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
172506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
175506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
182085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1836217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
184085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1876217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
189085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
191085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
192465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
197085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
198b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May
199b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
2001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth                                  unsigned int Num) {
2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (Attr.getNumArgs() != Num) {
2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    return false;
2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  }
2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  return true;
2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth}
2091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
210db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
211b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May
212b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                  unsigned int Num) {
215b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (Attr.getNumArgs() < Num) {
216db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
217db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return false;
218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  return true;
221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
223db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski///
224fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var
225fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable
226fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
22739997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) {
228fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (isa<FieldDecl>(D))
229fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return true;
23039997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const VarDecl *vd = dyn_cast<VarDecl>(D))
231fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
232fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
235fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
236b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool.
237b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) {
238b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = Exp->getType();
239b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return QT->isBooleanType() || QT->isIntegerType();
240b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
241b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
242aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
243aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// Check to see if the type is a smart pointer of some kind.  We assume
244aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// it's a smart pointer if it defines both operator-> and operator*.
24560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchinsstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
24660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
24760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
24860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (Res1.first == Res1.second)
24960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return false;
25060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
25160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
25260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
25360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (Res2.first == Res2.second)
25460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return false;
25560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
25660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  return true;
257aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins}
258aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type.
260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message.
261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise
262ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
263ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                       const AttributeList &Attr) {
26439997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
265fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
26639997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer    if (QT->isAnyPointerType())
267fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
268aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
26960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    if (const RecordType *RT = QT->getAs<RecordType>()) {
27060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // If it's an incomplete type, it could be a smart pointer; skip it.
27160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // (We don't want to force template instantiation if we can avoid it,
27260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // since that would alter the order in which templates are instantiated.)
27360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      if (RT->isIncompleteType())
27460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins        return true;
27560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
27660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      if (threadSafetyCheckIsSmartPointer(S, RT))
27760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins        return true;
27860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    }
279aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
280ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
281fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
282fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
283fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
284fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
285fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
286fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
287fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
288fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
289b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points
290b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit.
2917d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) {
2927d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const RecordType *RT = QT->getAs<RecordType>())
293b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return RT;
2947d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2957d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  // Now check if we point to record type.
2967d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const PointerType *PT = QT->getAs<PointerType>())
2977d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer    return PT->getPointeeType()->getAs<RecordType>();
2987d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2997d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  return 0;
300b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
301b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
302bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
303bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchinsbool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
304bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins                                      CXXBasePath &Path, void *UserData) {
305bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  const RecordType *RT = Specifier->getType()->getAs<RecordType>();
306bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (RT->getDecl()->getAttr<LockableAttr>())
307bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    return true;
308bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  return false;
309bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins}
310bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
311bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
3123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType
313ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// resolves to a lockable object.
31483cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchinsstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
31583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins                                   QualType Ty) {
31683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  const RecordType *RT = getRecordType(Ty);
31783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins
31883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  // Warn if could not get record type for this argument.
319d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT) {
320ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
32183cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      << Attr.getName() << Ty.getAsString();
32283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
3233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
32460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
325634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  // Don't check for lockable if the class hasn't been defined yet.
326634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  if (RT->isIncompleteType())
32783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
32860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
32960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  // Allow smart pointers to be used as lockable objects.
33060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  // FIXME -- Check the type that the smart pointer points to.
33160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (threadSafetyCheckIsSmartPointer(S, RT))
33260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return;
33360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
334bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  // Check if the type is lockable.
335bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  RecordDecl *RD = RT->getDecl();
336bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (RD->getAttr<LockableAttr>())
33783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
338bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
339bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  // Else check if any base classes are lockable.
340bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
341bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    CXXBasePaths BPaths(false, false);
342bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths))
343bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins      return;
3443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
345bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
346bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
347bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    << Attr.getName() << Ty.getAsString();
3483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
350b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
351ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// from Sidx, resolve to a lockable object.
3523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with.
3533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function
3543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list.
355ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
3563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         const AttributeList &Attr,
3573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         SmallVectorImpl<Expr*> &Args,
358b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
359b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
3603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
361b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
3623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
363ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    if (ArgExp->isTypeDependent()) {
364ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // FIXME -- need to check this again on template instantiation
365ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      Args.push_back(ArgExp);
366ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      continue;
367ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    }
368b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
36979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
37079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      // Ignore empty strings without warnings
37179747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (StrLit->getLength() == 0)
37279747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        continue;
37379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
374ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // We allow constant strings to be used as a placeholder for expressions
375ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // that are not valid C++ syntax, but warn that they are ignored.
376ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
377ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins        Attr.getName();
378ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      continue;
379ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    }
380ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins
3813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
382b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
38379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // A pointer to member expression of the form  &MyClass::mu is treated
38479747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // specially -- we need to look at the type of the member.
38579747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
38679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (UOp->getOpcode() == UO_AddrOf)
38779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
38879747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins          if (DRE->getDecl()->isCXXInstanceMember())
38979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins            ArgTy = DRE->getDecl()->getType();
39079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
3913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
393b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
397b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
398b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
399b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
400b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
4013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
4023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
4033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
404b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
405b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
406ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins          continue;
407b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
4083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
409b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
410b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
411b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
41283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    checkForLockableRecord(S, D, Attr, ArgTy);
413b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
415b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
416b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
417b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
418e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
419e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
420e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
421e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
4223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
4233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
4243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
4253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
427fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
428fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
436b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
440ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
444768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
446768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
449db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
450b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
451db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
452db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
453b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
455db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
456db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
457db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
458db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
459b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
460db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
462db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
463ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
464db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
465db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
466ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  SmallVector<Expr*, 1> Args;
467ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // check that all arguments are lockable objects
468ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
469ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  unsigned Size = Args.size();
470ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size != 1)
471ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
472ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr *Arg = Args[0];
473b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
474db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
475768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
4763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 S.Context, Arg));
477db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
478768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
479db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
480db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
482fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
483fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
484fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
485fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
486fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
487fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
488fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4891748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
490fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
491fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
492fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
493fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
494fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
495fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
496fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
497768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
498fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
499768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
500fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
501fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
502fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
503fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
504fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
505fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
506fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
507fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
508fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
509b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
510fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
511fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
512fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
513fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
514fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
515768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
516fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
517fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
518fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
51971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D,
520ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                      const AttributeList &Attr) {
52171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  assert(!Attr.isInvalid());
52271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
52371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!checkAttributeNumArgs(S, Attr, 0))
52471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
52571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
52671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
52771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
52871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany      << Attr.getName() << ExpectedFunctionOrMethod;
52971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
53071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  }
53171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
53271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
53371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany                                                          S.Context));
53471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany}
53571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
537db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
538db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
539db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
540b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
541db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
542db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
543db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
544b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
545b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
546db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
547b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
549db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
550db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
551ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that this attribute only applies to lockable types.
552b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
553b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
554b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
555b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
556ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
557b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
558b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
559b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
560b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
561b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
563ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that all arguments are lockable objects.
564ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
5653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
566ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
567ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
568ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
5693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
571768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
5723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                    StartArg, Size));
573db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
574768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
5753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                   StartArg, Size));
576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
577db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
579b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
580db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
583db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
584b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
585b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
586db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
587db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
591b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
593ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
5943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
597db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
598768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
5993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
6003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
601db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
602768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
6033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        S.Context, StartArg,
6043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        Size));
605db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
606db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
607db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
608b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
609db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
610db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
611b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
612db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
613db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
614b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
615db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
616db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
617db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
620b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
621b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
622b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
623b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
624b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
625b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 2> Args;
627b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
628ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
6293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
633768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
6343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              S.Context,
63569f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                              Attr.getArg(0),
6363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              StartArg, Size));
637db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
638768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
63969f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           S.Context,
64069f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           Attr.getArg(0),
64169f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           StartArg, Size));
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
645b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
646db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
647db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
648b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
650db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
651b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
652db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
656db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
657b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
659ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
6603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
661ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
662ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
663ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
6643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
666768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
6673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            S.Context, StartArg,
6683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            Size));
669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
670768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
6713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         S.Context, StartArg,
6723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         Size));
673db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
674db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
675db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
676b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
677db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
678db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
679db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
680db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
681b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
682db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
683db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
684db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
685db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
686db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
687b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
689ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
6903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
693768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
6943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
695db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
696db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
697db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
698b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
699db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
700db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
701b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
702db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
7033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
704db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
705b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
706db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
707db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
708db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
709db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
710db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
7113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
712b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
713b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
7143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
715f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  SmallVector<Expr*, 1> Args;
716f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
717f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  unsigned Size = Args.size();
718f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  if (Size == 0)
719f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins    return;
7203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
721f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context,
722f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins                                                Args[0]));
723db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
724db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
725db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
726b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
727db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
728db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
729b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
730db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
731db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
732b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
733db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
734db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
735db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
736db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
737db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
738b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
7393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
740ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
7413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
742ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
743ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
744ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
7453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
746768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
7473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
748db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
749db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
750db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
7511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
7521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
75387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
754545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
755803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
756545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
7576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
758bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
7609cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7619cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
7629cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7639cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
7649cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
765f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
766e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    SourceLocation TemplateKWLoc;
767f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
768f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
7694ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
770e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id,
771e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                          false, false);
7724ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
7734ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
7744ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
7754ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
7769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
7779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
7781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
7799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
7801731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
7817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
7826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
7859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
7869ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
7879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
788ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
789a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
790bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
7929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
7936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
7981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
7996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
800bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
80187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
802768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
80387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
8046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
8056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
8066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
807803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
808fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
80908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
8106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
811768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
8126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
8133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
8146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
81787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
818768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
819c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
820c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
821c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
822c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
8231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
82496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
8251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
82696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
827bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
82863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
82987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
83063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
831768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
83263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
83363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
83463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8354ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
83663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
83763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8382f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
8392f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // The IBOutlet/IBOutletCollection attributes only apply to instance
8402f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // variables or properties of Objective-C classes.  The outlet must also
8412f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // have an object reference type.
8422f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
8432f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
8440bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
8452f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << VD->getType() << 0;
8462f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
8472f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
8482f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
8492f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
8502f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
851f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
8522f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << PD->getType() << 1;
8532f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
8542f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
8552f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
8562f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else {
8572f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
8582f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    return false;
8592f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
860f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
8612f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  return true;
8622f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek}
8632f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
86563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
8661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
86763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
8682f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8692f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
87063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
87163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8722f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
87396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
87496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
8751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
8761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
877857e918a8a40deb128840308a318bf623d68295fTed Kremenek
878857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
879a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
880857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
881857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
882857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
883857e918a8a40deb128840308a318bf623d68295fTed Kremenek
8842f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
885857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
8862f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
887a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
888a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
889f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian    II = &S.Context.Idents.get("NSObject");
8903a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
891b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
89287c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
893a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
894a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
895a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
896a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
897b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
898a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
899a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
900a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
901a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
902f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
903a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
904a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
905a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
906f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
907f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
908857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
909857e918a8a40deb128840308a318bf623d68295fTed Kremenek
910d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
91168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
91268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
91368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
91468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
91568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
91668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
91768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
91868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
91968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
92068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
92168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
92268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
92368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
92468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
9251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
926bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
92887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
929fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
930883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
931eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
932eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
933bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
93407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
93507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
93687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
93787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
938eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
939eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
9405f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
941bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
942eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
943eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
944bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
945bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
946eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
9477a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
948eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
949ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
950ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
951fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
952fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
953eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
954eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
955bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
956eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
957bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
958eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
959fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
96030bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
961eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
962eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
963bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
964465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
96507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
96607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
96707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
96807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
96907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
97007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
97107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
97207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
97307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
974eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
975eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
97687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
977d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
97868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
979dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
980eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
981c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
982fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
9837fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
984eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
985bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
986eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
987eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
988bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
990bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
9917fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
99287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
99387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
994d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
995dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
996d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
99746bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
998bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
999ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
100060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
100160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
100260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
100360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
100460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
10057fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
100660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
1007eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
10087fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
10097fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
10107fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
1011dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1012768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
1013cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
1014eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
1015eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
10161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
1019dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
1020dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
1021dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
1022dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
10232a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
10242a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
1025dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1026dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
1027dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1030dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1031dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
1032cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
10332a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
10342a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
1035cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
1036dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
1037dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
10402a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
10412a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
1042cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
1043dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
1044dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1045dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1046dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
10472a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
10482a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
1049cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
1052dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
1053dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
10552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
10562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
10572a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
10582a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
1059dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1060dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
106187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
1062883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1063883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
1064dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1065dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1066dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
106707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
106807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
106987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
107087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
1073dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1074dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
1075dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
1076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
1077dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
1079dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10802a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
10812a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1082dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10837a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1084dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1085dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1086dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1087dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1088dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1089dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1090dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1091dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1092dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1093dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1094dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1095dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1096dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1097dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1098dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1099dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
110007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
110107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
110207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
110307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
110407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
110507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
110607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
110707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
110807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1109dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1110cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1111cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1112dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
111387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1114dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1115dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1116dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1117cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1118dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1119dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1120dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1121dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1122dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1123dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1124cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1125dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1126dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
11277a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1128dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1129dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1130dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1131dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1132dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1133dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1134dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1135dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1136dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1137dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1138dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1139dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1140dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1141dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1142cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
114387c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
114487c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1145cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1146cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1147cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1148cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1149cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1150cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1151cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1152dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1153dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1154dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1155dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1156dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1157dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1158dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1159dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1160dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1161dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1162cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1163cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1164cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1165cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1166dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1167cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
116887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1169cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1170dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1171dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1172332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1173332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1174332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1175332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1176332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1177332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1178332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1179332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1180332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1181332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1182332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1183332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1184332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1185332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1186332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1187332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1188332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
118911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
119011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
119211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
119311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
119411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
119511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
119611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
119711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
119887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1199332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1200883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1201332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1202332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1203332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
120487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1205332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
120611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
120711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
120811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
120911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
121011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
121111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
121211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
121311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
121411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
121511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
121687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
12177a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
12187a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1219332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
12207a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
122111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
122211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
122311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
122411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
122511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
122611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
122711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
122811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
122911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
123011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
123111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
123211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
123311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
123411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
123511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
123611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
123711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
123811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
123911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
124011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1241332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1242332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
124311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
124411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
124511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
124611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
124711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
124811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
124911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
125011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
12517a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
125211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
125311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
125411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
12555cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
125611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
125711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
125811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
125911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
126011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
126111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1262768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1263f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
126411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
126511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1266768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
126711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
126811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
12691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
12706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1271545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
12723c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1275bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
12776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
12786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1279bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12805cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1281fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
12836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1285bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1286bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1287f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1288f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1289f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1290f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
12916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1292bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1293768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1294f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
12956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1298dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
12991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1300dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1301dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
130287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1303dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1304883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1305dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1306dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1307dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1308768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1309dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1310dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
13111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
13121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1313dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1314831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
13153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1316af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1317af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
13185bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
131987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
13205bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1321883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
13225bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
13235bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1324bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1325768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1326af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1327af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
13281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1329dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1330831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
133176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
133276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
133376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
13341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
133587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
13361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
13372cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1338768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
13392cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
13402cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1341fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1342fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
13432cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
134476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
134576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
13461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
134734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
13481731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
134934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
135034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1351768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
135234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
135334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
13541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
135556aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
135687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1357768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1358722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1359722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1360883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1361a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1362a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
13631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
136456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
136587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1366768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1367722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1368722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1369883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1370a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1371a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
13721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
137387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1374711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1375711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1376711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
137787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1378711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1379883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1380711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1381711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1382711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1383768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1384711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1385711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1386711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1387831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1388711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1389711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1390711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1391711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1392711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1393711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1394b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1395b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
13971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1398b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1399b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1400b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1401b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
14021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
14031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1404b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
140587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
140687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
14073ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
14083ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1409e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1410e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1411b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1412883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1413b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
141419c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
14156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1416b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1417768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
14186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
142035cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
14211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
142235cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
142335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
142435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1425f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1426f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1427f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1428f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1429f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
143035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
143135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
143235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
143335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
143435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
143535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
143635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
143735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
143835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
143935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
144035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
144135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
144235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
144335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
144435cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
144587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
144635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1447883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
144835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
144935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
145035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
145187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
145235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
145335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
145435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
145535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
145687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
145701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
145801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
145901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
146001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
146101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
146201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
146301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
146401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
146501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
146601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
146701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
146801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1469f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1470f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
147101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
147201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
147301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
147401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
147501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
147601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
147701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1478768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
147935cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
148035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
14811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
148287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1483bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1484883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1485bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1486bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1487bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1488bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1489bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
14901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
149173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1492831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
149473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
149573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1496bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
149787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
149887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1499fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1500883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
150173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
150273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1503bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1504768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
150573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
150673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1507f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1508f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1509f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1510f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1511f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1512f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1513f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1514f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1515f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1516f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1517f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1518f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1519f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1520f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1521f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1522f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1523f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
15241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1525b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1526831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1527b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1528b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1529b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1530bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
153187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1532186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1533b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1534b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1535b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
153687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1537b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1538883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1539b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1540b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1541bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1542768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1543b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1544b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
15451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1547bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1548bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
15493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1550bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
15533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
15547a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
15553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1556ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1557ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1558fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
15603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1564bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
156587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1566fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1567883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1571768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1572f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
15733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1577bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1578bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
15793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1580bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
15833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
15847a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
15853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1586ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1587ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1588fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
15903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1594bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
159587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1596fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1597883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
16003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1601768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1602f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
16033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
16043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
16051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1606951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1607951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1608bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1609c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1610c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1611951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1612c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
16135f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1614951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1615951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1616c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1617951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1618951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1619c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1620c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1621951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
16226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1623bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1624768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str));
16256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
16266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1628951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1629951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1630bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1631bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1632bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1633951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1634c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
16355f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1636951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1637951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1638c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1639951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1640c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1641c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1642c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1643951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1644c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1645768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str));
1646bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1647bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1648742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1649742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1650742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1651742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1652742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1653742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1654742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1655742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1656742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1657768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1658742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1659742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1660b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beardstatic void handleObjCRootClassAttr(Sema &S, Decl *D,
1661b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard                                    const AttributeList &Attr) {
1662b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (!isa<ObjCInterfaceDecl>(D)) {
1663b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1664b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1665b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1666b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1667b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  unsigned NumArgs = Attr.getNumArgs();
1668b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (NumArgs > 0) {
1669b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1670b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1671b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1672b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1673b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
1674b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard}
1675b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
167671207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
1677e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                            const AttributeList &Attr) {
1678341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  if (!isa<ObjCInterfaceDecl>(D)) {
1679341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
1680341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    return;
1681341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  }
1682341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian
1683e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1684e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  if (NumArgs > 0) {
1685e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1686e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    return;
1687e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  }
1688e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
168971207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
1690e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                 Attr.getRange(), S.Context));
1691e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian}
1692e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
16933b294360febd89e3383143af086efe2014571afaRafael Espindolabool checkAvailabilityAttr(Sema &S, SourceRange Range,
16943b294360febd89e3383143af086efe2014571afaRafael Espindola                           IdentifierInfo *Platform,
16953b294360febd89e3383143af086efe2014571afaRafael Espindola                           VersionTuple Introduced,
16963b294360febd89e3383143af086efe2014571afaRafael Espindola                           VersionTuple Deprecated,
16973b294360febd89e3383143af086efe2014571afaRafael Espindola                           VersionTuple Obsoleted) {
16985f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
16990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
17003b294360febd89e3383143af086efe2014571afaRafael Espindola  if (PlatformName.empty())
17010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
17020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1703c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
17040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
17053b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Introduced.empty() && !Deprecated.empty() &&
17063b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Introduced <= Deprecated)) {
17073b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
17083b294360febd89e3383143af086efe2014571afaRafael Espindola      << 1 << PlatformName << Deprecated.getAsString()
17093b294360febd89e3383143af086efe2014571afaRafael Espindola      << 0 << Introduced.getAsString();
17103b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
17110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
17120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
17133b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Introduced.empty() && !Obsoleted.empty() &&
17143b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Introduced <= Obsoleted)) {
17153b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
17163b294360febd89e3383143af086efe2014571afaRafael Espindola      << 2 << PlatformName << Obsoleted.getAsString()
17173b294360febd89e3383143af086efe2014571afaRafael Espindola      << 0 << Introduced.getAsString();
17183b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
17193b294360febd89e3383143af086efe2014571afaRafael Espindola  }
17203b294360febd89e3383143af086efe2014571afaRafael Espindola
17213b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Deprecated.empty() && !Obsoleted.empty() &&
17223b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Deprecated <= Obsoleted)) {
17233b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
17243b294360febd89e3383143af086efe2014571afaRafael Espindola      << 2 << PlatformName << Obsoleted.getAsString()
17253b294360febd89e3383143af086efe2014571afaRafael Espindola      << 1 << Deprecated.getAsString();
17263b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
17273b294360febd89e3383143af086efe2014571afaRafael Espindola  }
17283b294360febd89e3383143af086efe2014571afaRafael Espindola
17293b294360febd89e3383143af086efe2014571afaRafael Espindola  return false;
17303b294360febd89e3383143af086efe2014571afaRafael Espindola}
17313b294360febd89e3383143af086efe2014571afaRafael Espindola
17323b294360febd89e3383143af086efe2014571afaRafael Espindolastatic void mergeAvailabilityAttr(Sema &S, Decl *D, SourceRange Range,
17333b294360febd89e3383143af086efe2014571afaRafael Espindola                                  IdentifierInfo *Platform,
17343b294360febd89e3383143af086efe2014571afaRafael Espindola                                  VersionTuple Introduced,
17353b294360febd89e3383143af086efe2014571afaRafael Espindola                                  VersionTuple Deprecated,
17363b294360febd89e3383143af086efe2014571afaRafael Espindola                                  VersionTuple Obsoleted,
17373b294360febd89e3383143af086efe2014571afaRafael Espindola                                  bool IsUnavailable,
17383b294360febd89e3383143af086efe2014571afaRafael Espindola                                  StringRef Message) {
17393b294360febd89e3383143af086efe2014571afaRafael Espindola  VersionTuple MergedIntroduced;
17403b294360febd89e3383143af086efe2014571afaRafael Espindola  VersionTuple MergedDeprecated;
17413b294360febd89e3383143af086efe2014571afaRafael Espindola  VersionTuple MergedObsoleted;
17423b294360febd89e3383143af086efe2014571afaRafael Espindola  bool FoundAny = false;
17433b294360febd89e3383143af086efe2014571afaRafael Espindola
17443b294360febd89e3383143af086efe2014571afaRafael Espindola  for (specific_attr_iterator<AvailabilityAttr>
17453b294360febd89e3383143af086efe2014571afaRafael Espindola         i = D->specific_attr_begin<AvailabilityAttr>(),
17463b294360febd89e3383143af086efe2014571afaRafael Espindola         e = D->specific_attr_end<AvailabilityAttr>();
17473b294360febd89e3383143af086efe2014571afaRafael Espindola       i != e ; ++i) {
17483b294360febd89e3383143af086efe2014571afaRafael Espindola    const AvailabilityAttr *OldAA = *i;
17493b294360febd89e3383143af086efe2014571afaRafael Espindola    IdentifierInfo *OldPlatform = OldAA->getPlatform();
17503b294360febd89e3383143af086efe2014571afaRafael Espindola    if (OldPlatform != Platform)
17513b294360febd89e3383143af086efe2014571afaRafael Espindola      continue;
17523b294360febd89e3383143af086efe2014571afaRafael Espindola    FoundAny = true;
17533b294360febd89e3383143af086efe2014571afaRafael Espindola    VersionTuple OldIntroduced = OldAA->getIntroduced();
17543b294360febd89e3383143af086efe2014571afaRafael Espindola    VersionTuple OldDeprecated = OldAA->getDeprecated();
17553b294360febd89e3383143af086efe2014571afaRafael Espindola    VersionTuple OldObsoleted = OldAA->getObsoleted();
17563b294360febd89e3383143af086efe2014571afaRafael Espindola    bool OldIsUnavailable = OldAA->getUnavailable();
17573b294360febd89e3383143af086efe2014571afaRafael Espindola    StringRef OldMessage = OldAA->getMessage();
17583b294360febd89e3383143af086efe2014571afaRafael Espindola
17593b294360febd89e3383143af086efe2014571afaRafael Espindola    if ((!OldIntroduced.empty() && !Introduced.empty() &&
17603b294360febd89e3383143af086efe2014571afaRafael Espindola         OldIntroduced != Introduced) ||
17613b294360febd89e3383143af086efe2014571afaRafael Espindola        (!OldDeprecated.empty() && !Deprecated.empty() &&
17623b294360febd89e3383143af086efe2014571afaRafael Espindola         OldDeprecated != Deprecated) ||
17633b294360febd89e3383143af086efe2014571afaRafael Espindola        (!OldObsoleted.empty() && !Obsoleted.empty() &&
17643b294360febd89e3383143af086efe2014571afaRafael Espindola         OldObsoleted != Obsoleted) ||
17653b294360febd89e3383143af086efe2014571afaRafael Espindola        (OldIsUnavailable != IsUnavailable) ||
17663b294360febd89e3383143af086efe2014571afaRafael Espindola        (OldMessage != Message)) {
17673b294360febd89e3383143af086efe2014571afaRafael Espindola      S.Diag(Range.getBegin(), diag::warn_mismatched_availability);
17683b294360febd89e3383143af086efe2014571afaRafael Espindola      S.Diag(OldAA->getLocation(), diag::note_previous_attribute);
17693b294360febd89e3383143af086efe2014571afaRafael Espindola      return;
17703b294360febd89e3383143af086efe2014571afaRafael Espindola    }
17713b294360febd89e3383143af086efe2014571afaRafael Espindola    if (MergedIntroduced.empty())
17723b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedIntroduced = OldIntroduced;
17733b294360febd89e3383143af086efe2014571afaRafael Espindola    if (MergedDeprecated.empty())
17743b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedDeprecated = OldDeprecated;
17753b294360febd89e3383143af086efe2014571afaRafael Espindola    if (MergedObsoleted.empty())
17763b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedObsoleted = OldObsoleted;
17770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
17780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
17793b294360febd89e3383143af086efe2014571afaRafael Espindola  if (FoundAny &&
17803b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedIntroduced == Introduced &&
17813b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedDeprecated == Deprecated &&
17823b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedObsoleted == Obsoleted)
17830a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
17843b294360febd89e3383143af086efe2014571afaRafael Espindola
17853b294360febd89e3383143af086efe2014571afaRafael Espindola  if (MergedIntroduced.empty())
17863b294360febd89e3383143af086efe2014571afaRafael Espindola    MergedIntroduced = Introduced;
17873b294360febd89e3383143af086efe2014571afaRafael Espindola  if (MergedDeprecated.empty())
17883b294360febd89e3383143af086efe2014571afaRafael Espindola    MergedDeprecated = Deprecated;
17893b294360febd89e3383143af086efe2014571afaRafael Espindola  if (MergedObsoleted.empty())
17903b294360febd89e3383143af086efe2014571afaRafael Espindola    MergedObsoleted = Obsoleted;
17913b294360febd89e3383143af086efe2014571afaRafael Espindola
17923b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!checkAvailabilityAttr(S, Range, Platform, MergedIntroduced,
17933b294360febd89e3383143af086efe2014571afaRafael Espindola                             MergedDeprecated, MergedObsoleted)) {
17943b294360febd89e3383143af086efe2014571afaRafael Espindola    D->addAttr(::new (S.Context) AvailabilityAttr(Range, S.Context,
17953b294360febd89e3383143af086efe2014571afaRafael Espindola                                                  Platform,
17963b294360febd89e3383143af086efe2014571afaRafael Espindola                                                  Introduced,
17973b294360febd89e3383143af086efe2014571afaRafael Espindola                                                  Deprecated,
17983b294360febd89e3383143af086efe2014571afaRafael Espindola                                                  Obsoleted,
17993b294360febd89e3383143af086efe2014571afaRafael Espindola                                                  IsUnavailable,
18003b294360febd89e3383143af086efe2014571afaRafael Espindola                                                  Message));
18010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
18023b294360febd89e3383143af086efe2014571afaRafael Espindola}
18030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
18043b294360febd89e3383143af086efe2014571afaRafael Espindolastatic void handleAvailabilityAttr(Sema &S, Decl *D,
18053b294360febd89e3383143af086efe2014571afaRafael Espindola                                   const AttributeList &Attr) {
18063b294360febd89e3383143af086efe2014571afaRafael Espindola  IdentifierInfo *Platform = Attr.getParameterName();
18073b294360febd89e3383143af086efe2014571afaRafael Espindola  SourceLocation PlatformLoc = Attr.getParameterLoc();
18083b294360febd89e3383143af086efe2014571afaRafael Espindola
18093b294360febd89e3383143af086efe2014571afaRafael Espindola  if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty())
18103b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
18113b294360febd89e3383143af086efe2014571afaRafael Espindola      << Platform;
18123b294360febd89e3383143af086efe2014571afaRafael Espindola
18133b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
18143b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
18153b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
18163b294360febd89e3383143af086efe2014571afaRafael Espindola  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
1817006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  StringRef Str;
1818006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  const StringLiteral *SE =
1819006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
1820006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  if (SE)
1821006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    Str = SE->getString();
18223b294360febd89e3383143af086efe2014571afaRafael Espindola
18233b294360febd89e3383143af086efe2014571afaRafael Espindola  mergeAvailabilityAttr(S, D, Attr.getRange(),
18243b294360febd89e3383143af086efe2014571afaRafael Espindola                        Platform,
18253b294360febd89e3383143af086efe2014571afaRafael Espindola                        Introduced.Version,
18263b294360febd89e3383143af086efe2014571afaRafael Espindola                        Deprecated.Version,
18273b294360febd89e3383143af086efe2014571afaRafael Espindola                        Obsoleted.Version,
18283b294360febd89e3383143af086efe2014571afaRafael Espindola                        IsUnavailable,
18293b294360febd89e3383143af086efe2014571afaRafael Espindola                        Str);
18300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
18310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
18321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
18341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
18356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1836bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18377a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
18386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
18396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1840bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18415cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1842fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
18433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
18446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1846bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1848cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1849bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1850c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1851cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1852c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1853cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1854c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1855cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
18564188760f6bb20f91c6883dffd89204419f852deeJohn McCall  else if (TypeStr == "protected") {
18574188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // Complain about attempts to use protected visibility on targets
18584188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // (like Darwin) that don't support it.
18594188760f6bb20f91c6883dffd89204419f852deeJohn McCall    if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
18604188760f6bb20f91c6883dffd89204419f852deeJohn McCall      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
18614188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Default;
18624188760f6bb20f91c6883dffd89204419f852deeJohn McCall    } else {
18634188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Protected;
18644188760f6bb20f91c6883dffd89204419f852deeJohn McCall    }
18654188760f6bb20f91c6883dffd89204419f852deeJohn McCall  } else {
186608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
18676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1869bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1870548d17c977959a5ed395ea1a407901f1314e575cRafael Espindola  // Find the last Decl that has an attribute.
1871548d17c977959a5ed395ea1a407901f1314e575cRafael Espindola  VisibilityAttr *PrevAttr;
1872548d17c977959a5ed395ea1a407901f1314e575cRafael Espindola  assert(D->redecls_begin() == D);
1873548d17c977959a5ed395ea1a407901f1314e575cRafael Espindola  for (Decl::redecl_iterator I = D->redecls_begin(), E = D->redecls_end();
1874548d17c977959a5ed395ea1a407901f1314e575cRafael Espindola       I != E; ++I) {
1875548d17c977959a5ed395ea1a407901f1314e575cRafael Espindola    PrevAttr = I->getAttr<VisibilityAttr>() ;
1876548d17c977959a5ed395ea1a407901f1314e575cRafael Espindola    if (PrevAttr)
1877548d17c977959a5ed395ea1a407901f1314e575cRafael Espindola      break;
1878548d17c977959a5ed395ea1a407901f1314e575cRafael Espindola  }
18794e31b4d6cf25029aa280d691e9023359c0ef4204Rafael Espindola
188045a0b264512ee0e9ba874bb3bfeb7f5b96789117Rafael Espindola  if (PrevAttr) {
188145a0b264512ee0e9ba874bb3bfeb7f5b96789117Rafael Espindola    VisibilityAttr::VisibilityType PrevVisibility = PrevAttr->getVisibility();
188245a0b264512ee0e9ba874bb3bfeb7f5b96789117Rafael Espindola    if (PrevVisibility != type) {
188345a0b264512ee0e9ba874bb3bfeb7f5b96789117Rafael Espindola      S.Diag(Attr.getLoc(), diag::err_mismatched_visibilit);
188445a0b264512ee0e9ba874bb3bfeb7f5b96789117Rafael Espindola      S.Diag(PrevAttr->getLocation(), diag::note_previous_attribute);
188545a0b264512ee0e9ba874bb3bfeb7f5b96789117Rafael Espindola      return;
188645a0b264512ee0e9ba874bb3bfeb7f5b96789117Rafael Espindola    }
188745a0b264512ee0e9ba874bb3bfeb7f5b96789117Rafael Espindola  }
1888768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type));
18896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
18906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
18921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1893d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1894d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
189587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1896883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1897d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1898d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1899d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
190087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
190187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
190287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1903d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1904d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
190587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1906d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
190787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1908d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1909d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1910d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
19115f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1912d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1913d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1914d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1915d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1916d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1917d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1918d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1919d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1920d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1921d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1922d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1923d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1924d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1925d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1926d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1927d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
192887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1929d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1930d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1931d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1932f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1933f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1934f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1935f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1936f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1937f85e193739c953358c865005855253af4f68a497John McCall    return;
1938f85e193739c953358c865005855253af4f68a497John McCall  }
1939f85e193739c953358c865005855253af4f68a497John McCall
1940768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
1941f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1942d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1943d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
19441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
19451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
19461731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
19470db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1948bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19490db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
19500db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
19510db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
19520db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
19530db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1954bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1955768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
19560db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
19570db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
19581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1959fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
19602b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1961fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1962fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1963162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1964fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1965fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
19666217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1967fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1968fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1969fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1970fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1971f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  else if (!isa<ObjCPropertyDecl>(D)) {
1972f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // It is okay to include this attribute on properties, e.g.:
1973f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1974f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
1975f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1976f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // In this case it follows tradition and suppresses an error in the above
1977f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // case.
19789b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
1979f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  }
1980768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
1981fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1982fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1983bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
19841b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1985f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
19862b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1987f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1988f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1989f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1990f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1991f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1992f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1993f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1994f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1995768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
1996f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1997f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
19981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1999bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2000fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
20013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
20029eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
20039eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2004bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20059eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
20063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
20079eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
20089eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2009bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2010cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
201192e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
20129eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
20139eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
2014fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
20153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
20169eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
20179eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2018bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2019768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
20209eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
20219eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
20221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2023770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
2024770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
2025bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
2026770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
2027bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2028bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20293323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
2030770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
20317a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
2032770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
2033ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2034ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
2035fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
20363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
2037770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2038770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2039bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20403323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
2041fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2042fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
2043770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2044770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
20453323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
20463323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
2047770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2048770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
20493323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
2050770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
20517a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
2052770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
2053ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2054ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
2055fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
20563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
2057770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2058770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2059770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
2060bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20613323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
2062770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
2063770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
2064fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2065fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
2066770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2067770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2068770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2069770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
207087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
20713323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
2072897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
2073897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
2074897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
2075897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
2076bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2077897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
20783bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2079770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2080bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
208187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
2082770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
20833bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2084770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
20852f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
2086a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
2087a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    if (!BD->isVariadic()) {
2088a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2089a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      return;
2090a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    }
209187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
20922f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
2093daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
209487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
2095f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
20962f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
20973bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
20983bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
20992f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
21002f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
2101ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
21022f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2103883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
21042f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
21052f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
2106770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
2107fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2108883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
2109770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
2110770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2111768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
2112f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
2113770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
2114770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
21151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
2116026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
21171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2118026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
2119026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
2120f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
2121026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2122883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
2123026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
2124026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
2125bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2126f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
2127f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2128f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
2129f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
2130f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
2131f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2132f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
2133f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2134f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
2135f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
2136f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
2137f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
2138768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
2139026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
2140026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
21411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
214387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
214487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
21456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
21476e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
214887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
214913c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    if (isa<CXXRecordDecl>(D)) {
215013c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
215113c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      return;
215213c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    }
215387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
215487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
2155f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
2156f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
2157f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
215887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
2159332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
2160332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
2161332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
216287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
21636e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
21646e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
2165bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2166768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
21676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
21686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21706e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
21711731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
21726e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
21731731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
21746e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
21756e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
21766e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
21770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
21780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
21790a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
21800a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
21810a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
2182def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2183bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
218490eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2185def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
2186def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
2187c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2188883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
21896e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
21906e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
21916e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
21926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
2193768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
21946e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
21956e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
21961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
21971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
21986f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
21991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
22006f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
22016f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
22026f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
22036f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
22047a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
22056f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
2206ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2207ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
22086f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
22096f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
22106f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
22116f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
22126f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
22136f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
2214768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
2215cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
22166f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
22176f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
22186f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
22191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
222017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
22211731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
222217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
222317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
222417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
222517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
22267a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2227797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
222817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
2229797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
223017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
223117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
22321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2233797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
2234bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2235a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2236a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2237a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2238797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2239797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
22401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2241a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2242a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2243a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2244a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2245a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2246a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
2247768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context,
2248f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
224917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
225017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
22516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
22536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2254831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
22553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
22566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2258b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
225987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2260b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2261ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2262b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2263768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2264b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
22656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
22666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2268232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2269831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
22703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2271232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2272232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2273bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
227487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2275b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2276ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2277b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2278768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2279b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2280232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2281232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
22821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2283232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
22841731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2285232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2286bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2287768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2288232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2289232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
22901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2291bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2292f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2293f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2294f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2295bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2296f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2297f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2298f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2299f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2300bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
230187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2302bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2303f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2304f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2305f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2306f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2307bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2308f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2309c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2310f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2311f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2312f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2313f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2314f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2315f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2316f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2317f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2318bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2319f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2320f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2321f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2322f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2323f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2324f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2325f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2326f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2327f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2328f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2329f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2330f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2331f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2332f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2333bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
233489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
233589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
233689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
233789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2338b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2339b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2340f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
234189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
234289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
234389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
234489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2345bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2346768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
23475f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
2348f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2349f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2351bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
23521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
23531731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
23545b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
23551731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
235687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
23575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2358883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
23605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
236107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
236207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
236307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
236487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
236587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
23665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
236707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
23685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
23697a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
23705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2371ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2372ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
23735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
23755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
23765b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2377bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
23795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
23805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
23815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
23825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2383bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2385bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
238607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
238707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
238807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
238907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
239007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
239107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
239207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
239307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
239407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
23955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
239687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2397bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
23995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
24005b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
24015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
24026217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
24035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
24045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2405bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
24065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
24075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2408bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
240987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
24105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
24115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
24125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
24136217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
24145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
24155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2416bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
24175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
24185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2419bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2420bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2421768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
242207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
24235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
24245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
24252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
24262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
24272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
24282b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
24292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
24303c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
24312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
24322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
24332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
24342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
24352b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
24365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
24372b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
24382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
24392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
24402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
24412b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
24422b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
24432b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
24442b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
24452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
24462b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
244769d53845c68a4f01920b58ba6ce507d78220689cJean-Daniel Dupas      Format == "strfmon" || Format == "cmn_err" || Format == "vcmn_err" ||
2448cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2449cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
24502b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
24512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2452bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2453bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
24543c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
24553c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
24562b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
24572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
24582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2459521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2460521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
24611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
24621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
24634e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!S.getLangOpts().CPlusPlus) {
2464521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2465521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2466521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2467521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
246887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2469b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2470b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2471b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2472b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
247387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2474b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2475b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2476b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2477b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2478b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2479b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2480b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2481b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2482521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2483521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2484521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2485521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2486521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
24877a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2488b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2489521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2490521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2491521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2492521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2493521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2494521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2495521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2496521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
24979f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2498521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2499521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2500521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2501521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2502521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2503521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2504768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2505f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2506521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2507521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2508bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2509bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
25101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2512545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2513fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
25143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
25156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2518545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
25193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
25206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
252387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2524fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2525883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
25266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
252907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
253007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
253187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
253287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
25336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
25346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25355f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
25366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
25382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
25392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
25402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
25412b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
25422b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
25433c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
25443c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
25453c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
25463c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
25472b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2548fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
254901eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
25506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
25547a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2555803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2556ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2557ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2558fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
25593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
25606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2564fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
25653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
25666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
25706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2571bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25724a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
25734a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
257407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
257507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
257607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
25774a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
25784a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
25794a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
25804a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
25811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
25826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
258387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
25846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2586085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2587fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2588fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2589085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2590085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
25912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2592390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2593390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2594803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2595390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2596fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2597fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
25986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2599bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
26006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
26016217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2602390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2603fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2604fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
26056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
26076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
26097a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2610803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2611ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2612ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2613fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
26143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
26156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
26176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
26196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
262087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
26216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
26226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
262387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
26246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
26256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
26266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
26276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
26293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
26302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
26316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2632fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2633fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
26346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
26356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
26366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
26376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2638fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
26393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
26406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
26426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2643b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2644b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
264587c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
264687c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2647b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2648b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2649b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2650b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2651b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2652b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2653b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2654b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2655ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis        f->setRange(Attr.getRange());
2656b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2657b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2658b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2659b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
2660768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format,
2661cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
26622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
26636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
26646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
26661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
26676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
26681731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
26696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26701731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
26716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
26730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
267487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
26750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
26760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
26770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
267887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
26790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
26800c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2681fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2682883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
26836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
26856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26865e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall  if (!RD->isCompleteDefinition()) {
2687bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
26880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
26890c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
26900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
26910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
269217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
269317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
26940c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
26950c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
26960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
26970c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2698bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
2699262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie  FieldDecl *FirstField = &*Field;
27000c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
270190cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2702bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
270390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
270490cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
27050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
27060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2707bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
27080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
27090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
27100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
27110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
27120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
27130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
27140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
27150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2716bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
27170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2718bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
27190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
27200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
27210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2722bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
27230c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
27240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2725bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2726bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2727bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
27286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2729768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
27306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
27316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
27336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
27341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
27356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
27361731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
27377a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2738797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2739bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
27406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
27416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
27426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2743797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
27446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
27456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
274677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
274777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
274877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
274977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
275077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
275177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
275277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
275377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
2754768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
2755f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
27566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
27576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
27596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2760545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
27613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
27626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
27636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2764bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2765bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2766bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2767bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
27686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2769545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2770768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0));
27714ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
27724ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
27734ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2774768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0));
27754ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
27764ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2777768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
27780b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  // FIXME: Handle pack-expansions here.
27790b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  if (DiagnoseUnexpandedParameterPack(E))
27800b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne    return;
27810b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne
27824ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
27834ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2784768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
27856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
27866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2787bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2788768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
2789cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
279049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
2791ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor  ExprResult ICE
2792ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor    = VerifyIntegerConstantExpression(E, &Alignment,
2793ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor        diag::err_aligned_attribute_argument_not_int,
2794ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor        /*AllowFold*/ false);
2795282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  if (ICE.isInvalid())
279649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
2797396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
27984ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
27994ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2800396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2801396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2802396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2803282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take()));
2804cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2805cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2806768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
2807cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2808cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2809768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS));
2810cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
28116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2812fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2813d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2814bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2815fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2816bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2817bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2818bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
28191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2820fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2821fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2822fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2823fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
28241731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2825fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
28261731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2827fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2828fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2829fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
28300b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2831fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2832fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2833210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
28345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2835fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2836fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2837210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2838210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2839fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2840fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2841fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
284273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2843210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2844fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
284573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
284673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
284773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
284873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
284973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
285073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
285173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
285273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
285373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
285473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
285573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
285673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
285773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
285873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
285973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
286073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2861fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2862fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2863fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2864fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2865210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
2866bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2867210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
2868bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
2869fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2870fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2871210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
2872bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2873fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2874fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2875fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2876fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2877162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2878fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2879fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2880fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2881fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2882fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2883768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
2884fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2885fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
288673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2887183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
288873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
288973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
28902ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
289173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
289273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
289373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
289473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
289573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
289673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
289773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
289873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
289973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2900390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2901390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2902390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2903390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2904f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2905f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2906fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2907fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2908fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
29093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2910fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2911fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
29123c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2913fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2914fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
291573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
291673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
291773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
291873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2919fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
29200b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2921fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
29220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2923fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2924fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
292573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
292673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
292773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
292873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2929fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
29300b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2931fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
29320b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2933fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2934fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2935fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
29360b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2937fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
29380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2939fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
29400b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2941fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2942fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2943fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
29440b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2945fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2946bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2947aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2948aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2949aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2950fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2951bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2952aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2953aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2954aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2955fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
295673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
295773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
295873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2959f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2960f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2961f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2962f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2963f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2964f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2965f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2966f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2967f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
296873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2969fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2970fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
297173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
297273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2973fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2974fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2975fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2976162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2977ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2978a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2979ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2980fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2981fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
29820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
29831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2984d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
29851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2986d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2987e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
298887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2989d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2990883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2991d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2992d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2993bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2994768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
2995d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2996d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
29971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
29985bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
29991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
30005bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
30011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3002bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
300387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
30045bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3005883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
30065bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
30075bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
3008bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3009768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
30105bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
30115bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
30121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
30131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
30147255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
30151731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
30167255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
30171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
30187255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
301987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
30207255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3021883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
30227255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
30237255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
30247255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
3025768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
3026f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
30277255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
30287255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
30291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3030ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3031ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
3032831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
3033ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3034ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3035ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3036ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
303787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
3038ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3039883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
3040ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3041ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3042ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3043768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
3044ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3045ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
3046ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3047ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3048ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
30491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3050ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3051ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
3052ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
3053ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3054ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3055ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3056ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
305787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
3058ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3059883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
3060ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3061ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3062ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3063768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
3064ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3065ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
3066ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3067ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3068ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
30691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3070ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3071ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
30721731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3073ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3074ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
307587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
3076ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3077883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
3078ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3079ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3080ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
308187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
30822c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
3083723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
30842c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
30852c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
30862c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
30872c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
30882c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
30892c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
30902c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
30912c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
30922c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
30932c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
30942c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
30952c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
3096768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
3097ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3098ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
3099ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3100ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3101ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
31021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3103ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3104ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
31051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3106ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
31071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3108ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
310987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
3110ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3111883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
3112ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3113ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3114ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3115768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
3116ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3117ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
3118ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3119ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3120ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
31211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3122ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3123ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
31241731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3125ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
31261731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3127ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
312887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
3129ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3130883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
3131ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3132ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3133ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3134768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
3135ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3136ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
3137ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3138ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3139ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
31401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
314126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
31421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
314326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
3144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
314587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
3146c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
314726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3148883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
314926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
315026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
3151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
31520130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
3153cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
3154c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
3155c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
3156bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3157768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
315826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
315926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
31601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
316187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3162711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
316387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
3164e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3165711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
316687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
3167711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3168e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
316987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
317087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
317187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3172711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3173711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3174711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
317587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3176e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
3177768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
3178e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3179e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
3180768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
3181e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3182f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
3183768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
318404633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
3185e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
3186768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
3187e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
318852fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3189768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
319052fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
3191414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
319287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
3193414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
31945cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
319587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3196414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
319787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3198414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3199414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3200414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
32015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3202414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
3203414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
3204414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
3205414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
3206414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
3207414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
320887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
320987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3210414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3211414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3212414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
3213768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
3214414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3215e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
3216e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
3217e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
3218e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
3219e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
32201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
322156aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
3222768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3223f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
3224f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
3225711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
3226711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
3227711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3228711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3229831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
3230831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
3231831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
3232711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3233711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
3234711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3235ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
323655d3aaf9a537888734762170823daf750ea9036dEli Friedman
3237414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3238414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3239711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
3240711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
3241711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
3242711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
3243711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
3244711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
3245414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
3246414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3247414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
32485cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3249414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3250414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3251414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3252414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3253414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3254414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
32555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3256414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3257414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3258414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3259414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3260414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3261414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3262414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3263414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3264414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
32657530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("unexpected attribute kind");
3266711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3267711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3268711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3269711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3270711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
32711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
327287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3273711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3274711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
327587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3276711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3277711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
327887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
327987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
328087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3281ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3282ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
328355d3aaf9a537888734762170823daf750ea9036dEli Friedman
3284768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3285711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3286711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3287711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3288711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
328987c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
329087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3291711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3292711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
329387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
329487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
329587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3296711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3297711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3298711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
329987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
330055d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3301ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3302711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
330387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
330455d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
330587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
330755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
330855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3309bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
331087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
331155d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
331287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3313711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
331455d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
331555d3aaf9a537888734762170823daf750ea9036dEli Friedman
3316711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3317bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
331887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3319bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
332087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3321711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
332255d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
332355d3aaf9a537888734762170823daf750ea9036dEli Friedman
3324711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3325ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3326ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
33271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
33287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
33297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
33307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3331bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3332bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
33337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
33347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
33357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
333687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
33377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3338883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
33397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
33407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
33417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
33427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
33437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
33447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
33457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
33467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
33477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
33487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
33497b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
33507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
33517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
33527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
33537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
33547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
33557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
33567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
33577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
33587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
33597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
33607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
33617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
33627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
33637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3364768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
33657b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
33667b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
33677b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
33687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
33697b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
33707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
33717b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
33720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3373b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3374b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3375b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3376c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
33776c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
33786c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isObjCObjectPointerType() ||
33796c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         S.Context.isObjCNSObjectType(type);
3380c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3381c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
33826c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
33836c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isPointerType() ||
33846c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         isValidSubjectOfNSAttribute(S, type);
3385c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3386c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
33871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
338887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3389c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
339087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3391768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3392c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3393c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3394c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3395c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
339687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3397c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3398c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3399c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3400c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3401c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3402c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3403c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3404c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
340587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3406768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3407c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3408c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3409c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3410c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3411768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3412c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3413768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3414c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3415c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
34161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
34171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
341887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
341987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3420768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3421c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3422c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3423c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3424768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3425c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3426c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
34271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
34281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3429b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3430c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3431bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
343287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3433c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
343487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3435831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
34364e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
343787c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3438f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
343987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3440c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
34415dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
344287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3443768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3444883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3445b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3446b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3447bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3448c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3449c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
345087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
34517530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("invalid ownership attribute");
3452c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3453c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3454c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3455c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3456c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3457c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3458c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3459c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3460c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3461c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3462c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3463c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3464c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3465c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3466c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
346787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3468768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3469bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
34705dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3471bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
347287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3473b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3474b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
3475c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
3476768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3477c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3478c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
347931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
3480768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3481f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
348231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
348331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
3484768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3485f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
348631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3487b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
3488768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3489f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3490b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3491b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
3492768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3493f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3494b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3495b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3496b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3497b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3498dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3499dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3500dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3501dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3502dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3503dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
350494d55d7ecdd693788a8f3910a0da1b5ecdaa8a86Fariborz Jahanian  if (!method) {
35050e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3506f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
3507dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3508dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3509dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3510dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3511dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3512f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian
3513f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3514f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3515dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3516dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3517dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3518dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3519dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3520dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3521dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3522dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3523dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3524768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3525dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3526dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
35278dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
35288dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
35298dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
35308dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3531f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << A.getRange() << A.getName() << ExpectedFunction;
35328dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
35338dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
35348dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
35358dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer);
35368dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
35378dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
35388dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
35398dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
35408dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
35418dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
35428dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
35438dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
35448dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
35458dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
35468dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
35478dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
35488dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
35498dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
35508dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
35518dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
35528dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
35538dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
35548dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
35558dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
35568dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
35578dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
35588dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
35598dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
35608dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
35618dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3562fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
3563fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
3564fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
3565fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
3566fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3567f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedStruct;
3568fe98da0fa352462c02db037360788748f95466f7John McCall  }
3569fe98da0fa352462c02db037360788748f95466f7John McCall
3570fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
3571fe98da0fa352462c02db037360788748f95466f7John McCall
3572fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
3573fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
3574fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
35754e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (ParmName && S.getLangOpts().ObjC1) {
3576fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
3577fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
3578fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
3579fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
3580fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
3581fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
3582fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
3583fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
3584fe98da0fa352462c02db037360788748f95466f7John McCall      }
3585fe98da0fa352462c02db037360788748f95466f7John McCall    }
3586fe98da0fa352462c02db037360788748f95466f7John McCall  }
3587fe98da0fa352462c02db037360788748f95466f7John McCall
3588fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
3589fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
3590fe98da0fa352462c02db037360788748f95466f7John McCall}
3591fe98da0fa352462c02db037360788748f95466f7John McCall
35921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
35931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
359487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3595f85e193739c953358c865005855253af4f68a497John McCall
359687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3597f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    << Attr.getRange() << Attr.getName() << ExpectedVariable;
3598f85e193739c953358c865005855253af4f68a497John McCall}
3599f85e193739c953358c865005855253af4f68a497John McCall
36001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
36011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
360287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
360387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3604f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedVariable;
3605f85e193739c953358c865005855253af4f68a497John McCall    return;
3606f85e193739c953358c865005855253af4f68a497John McCall  }
3607f85e193739c953358c865005855253af4f68a497John McCall
360887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3609f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3610f85e193739c953358c865005855253af4f68a497John McCall
3611f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3612f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
361387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3614f85e193739c953358c865005855253af4f68a497John McCall      << type;
3615f85e193739c953358c865005855253af4f68a497John McCall    return;
3616f85e193739c953358c865005855253af4f68a497John McCall  }
3617f85e193739c953358c865005855253af4f68a497John McCall
3618f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3619f85e193739c953358c865005855253af4f68a497John McCall
3620f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3621f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3622f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3623f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3624f85e193739c953358c865005855253af4f68a497John McCall
3625f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3626f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3627f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3628f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3629f85e193739c953358c865005855253af4f68a497John McCall    break;
3630f85e193739c953358c865005855253af4f68a497John McCall
3631f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3632f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3633f85e193739c953358c865005855253af4f68a497John McCall    break;
3634f85e193739c953358c865005855253af4f68a497John McCall
3635f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3636f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
363787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3638f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3639f85e193739c953358c865005855253af4f68a497John McCall    break;
3640f85e193739c953358c865005855253af4f68a497John McCall  }
3641f85e193739c953358c865005855253af4f68a497John McCall
364287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3643768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3644f85e193739c953358c865005855253af4f68a497John McCall}
3645f85e193739c953358c865005855253af4f68a497John McCall
3646f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
36479428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  switch (Attr.getKind()) {
36489428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  default:
36499428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return false;
36509428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllimport:
36519428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllexport:
36529428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_uuid:
36539428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_deprecated:
36549428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noreturn:
36559428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_nothrow:
36569428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_naked:
36579428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noinline:
36589428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return true;
36599428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  }
366011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
366111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
366211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
366311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
366411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
366511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
36661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
366762ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
366811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
36691731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
367011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
36711731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
367211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
367311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
36745cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3675d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3676d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3677d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3678d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3679d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
36805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3681d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3682d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3683d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3684f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
3685d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3686d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3687d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3688d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3689d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3690d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3691d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3692d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3693d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3694d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3695f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3696d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
36975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3698f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3699f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3700f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3701f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3702d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3703d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3704d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3705d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3706d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3707d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3708d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3709d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3710d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3711d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3712d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
371311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
3714768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
371511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3716d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
371711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3718f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3719f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3720b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
37210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
37220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
37230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
37241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
37251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
372660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
37271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
37281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
37291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
373060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
373160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
373260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
373360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3734e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
37351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
37361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3737803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
3738e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_ibaction:            handleIBAction(S, D, Attr); break;
3739e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutlet:          handleIBOutlet(S, D, Attr); break;
3740e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutletcollection:
37411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3742803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3743207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3744ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
37456e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
37464211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
37474211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3748bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3749bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3750803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
375160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
375260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
375360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
375460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
375560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
375660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
37571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
37581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3759bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
37601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3761b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
37621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
37631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
37641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3765bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
37661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
37671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
37681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
37691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
37701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
37711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
37723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
37731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
37743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
37751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
37761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
37771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
37781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
37797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
37801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
37817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
37821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
37831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
37841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
37851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
37861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3787dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3788dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3789dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
37901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
37911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
37921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
37931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
37941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
37951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3796b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3797b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
37981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3799f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
38001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3801f85e193739c953358c865005855253af4f68a497John McCall
3802dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3803dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3804dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3805fe98da0fa352462c02db037360788748f95466f7John McCall  case AttributeList::AT_ns_bridged:
3806fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
3807fe98da0fa352462c02db037360788748f95466f7John McCall
38088dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_audited_transfer:
38098dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_unknown_transfer:
38108dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
38118dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3812b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3813c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
38141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3815c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
38161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3817c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3818c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
381931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
382031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3821b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3822b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
38231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3824b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3825e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_reqd_work_group_size:
38261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
38276f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3828521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
38291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3830521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
38311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
3832e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_ms_struct:    handleMsStructAttr    (S, D, Attr); break;
38331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
38341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3835e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_objc_arc_weak_reference_unavailable:
3836742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3837742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
3838b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  case AttributeList::AT_objc_root_class:
3839b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    handleObjCRootClassAttr(S, D, Attr);
3840b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    break;
384171207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  case AttributeList::AT_objc_requires_property_definitions:
384271207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
3843e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    break;
38441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
3845f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  case AttributeList::AT_returns_twice:
3846f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
3847f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
38481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
38491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
38501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3851026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
38521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
38531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
38541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3855803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
38561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3857803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
38580db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
38591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
38600db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3861d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
38621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3863d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
3864e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_NSObject:    handleObjCNSObject    (S, D, Attr); break;
38651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
38661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
38671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
38681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
38691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
38701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
38711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
38721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3873bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
387405f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
387505f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
38767255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
38771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
38787255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
387904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
388004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
388104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3882f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
388352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3884414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
38851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
388604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3887f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
38881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3889f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
389011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
38911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
389211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3893fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3894fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3895fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3896fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3897fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3898fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3899fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3900fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3901fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3902fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3903fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
390471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  case AttributeList::AT_no_address_safety_analysis:
390571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    handleNoAddressSafetyAttr(S, D, Attr);
390671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    break;
3907fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3908fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3909fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3910fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3911fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3912fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3913db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3914db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3915db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3916db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3917db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3918db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3919db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3920db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3921db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3922db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3923db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3924db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3925db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3926db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3927db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3928db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3929db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3930db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3931db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3932db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3933db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3934db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3935db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3936db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3937db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3938db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3939db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3940db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3941db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3942db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3943db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3944db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3945db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3946db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3947db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3948db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3949db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3950db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3951db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3952fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3953803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
395482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
395582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
395682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
39577d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
39587d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3959803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3960803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3961803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3962803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
396360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
396460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
396560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
396660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
39671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
39681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
396960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
397060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
397160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
397260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
397360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
397460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
397560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
397660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
397760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
39781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
397960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
398060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
39811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
398260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
398360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3984803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3985803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3986f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
398760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
398860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
398911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
39901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
399111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
399211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
399311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
399411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
399511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
399660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
399711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3998dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
399911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
4000803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
4001803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
4002803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
40035f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access
40045f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier.
40055f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
40065f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          const AttributeList *AttrList) {
40075f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
40085f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    if (l->getKind() == AttributeList::AT_annotate) {
40095f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      handleAnnotateAttr(*this, ASDecl, *l);
40105f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    } else {
40115f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
40125f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      return true;
40135f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    }
40145f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  }
40155f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
40165f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  return false;
40175f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen}
40185f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
4019e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
4020e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
4021e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
4022e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
4023e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
4024e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
4025e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
4026e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4027e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
4028e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
4029e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
4030e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
4031e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
4032e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
4033e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
4034e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
4035e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
4036e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4037e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
4038e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
4039e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
4040e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
4041e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
4042e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
4043e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
4044e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
4045e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
4046e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4047e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
4048e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
4049900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
4050900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
40517b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
4052e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
4053e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
4054900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
4055900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
4056900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
4057900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
4058900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
4059900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
4060900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
4061900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
4062900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
4063900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
4064900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
4065900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
4066900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
4067900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
4068900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
4069c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
4070900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
4071900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
4072900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
4073900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
4074900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
4075900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
4076900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
4077900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
4078900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
4079900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
4080900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
4081900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
40824278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
4083b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
4084e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
4085e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
4086ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
4087a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
408816573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
408916573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
4090b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
4091b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
4092c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
4093b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
4094e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4095e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
4096e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
4097e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
4098e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
4099e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
41007b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
4101c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
4102c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
4103c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
4104c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
4105900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
4106cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
4107cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
4108cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
4109c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
4110c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
4111c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
4112c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
4113c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
4114c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
4115c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
4116c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
4117cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
4118e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4119e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
4120e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
41210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
41220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
41230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
412460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
412560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
4126d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
4127d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
412831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
412931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
413031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
413131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
413231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
413331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
413431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
413531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
413631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
413731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
413831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
413931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
4140d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
4141e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
4142e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
4143e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4144e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
41450744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
41467f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
414760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4148bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
41490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
41500744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
41510744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
41520744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
41530744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
41540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
415560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4156bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
41570744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
41580744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
415960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
41600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
416154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4162f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
4163f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
4164f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
4165f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
4166f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
4167a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
4168a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
4169a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
4170f85e193739c953358c865005855253af4f68a497John McCall    return false;
4171f85e193739c953358c865005855253af4f68a497John McCall
4172f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
4173f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
4174f85e193739c953358c865005855253af4f68a497John McCall}
4175f85e193739c953358c865005855253af4f68a497John McCall
4176f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
4177f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4178f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
4179f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
4180f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
4181f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
4182f85e193739c953358c865005855253af4f68a497John McCall    return;
4183f85e193739c953358c865005855253af4f68a497John McCall  }
41844e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (S.getLangOpts().ObjCAutoRefCount)
4185175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
4186175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // FIXME. we may want to supress diagnostics for all
4187175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // kind of forbidden type messages on unavailable functions.
4188175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
4189175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag.getForbiddenTypeDiagnostic() ==
4190175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
4191175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
4192175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
4193175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
4194175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
4195f85e193739c953358c865005855253af4f68a497John McCall
4196f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4197f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4198f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
4199f85e193739c953358c865005855253af4f68a497John McCall}
4200f85e193739c953358c865005855253af4f68a497John McCall
42019257664568bf375b7790131a84d9a4fa30a5b7e3John McCallvoid Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
42029257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  assert(DelayedDiagnostics.getCurrentPool());
42039257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  sema::DelayedDiagnosticPool &poppedPool =
42049257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    *DelayedDiagnostics.getCurrentPool();
42059257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  DelayedDiagnostics.popWithoutEmitting(state);
42069257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
42079257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // When delaying diagnostics to run in the context of a parsed
42089257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // declaration, we only want to actually emit anything if parsing
42099257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // succeeds.
42109257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  if (!decl) return;
42119257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
42129257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // We emit all the active diagnostics in this pool or any of its
42139257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // parents.  In general, we'll get one pool for the decl spec
42149257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // and a child pool for each declarator; in a decl group like:
42159257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  //   deprecated_typedef foo, *bar, baz();
42169257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // only the declarator pops will be passed decls.  This is correct;
42179257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // we really do need to consider delayed diagnostics from the decl spec
42189257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // for each of the different declarations.
42199257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  const sema::DelayedDiagnosticPool *pool = &poppedPool;
42209257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  do {
42219257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    for (sema::DelayedDiagnosticPool::pool_iterator
42229257664568bf375b7790131a84d9a4fa30a5b7e3John McCall           i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
42239257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      // This const_cast is a bit lame.  Really, Triggered should be mutable.
42249257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
4225eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
42262f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
42272f514480c448708ec382a684cf5e035d3a827ec8John McCall
4228eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
42292f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
4230e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        // Don't bother giving deprecation diagnostics if the decl is invalid.
4231e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        if (!decl->isInvalidDecl())
42329257664568bf375b7790131a84d9a4fa30a5b7e3John McCall          HandleDelayedDeprecationCheck(diag, decl);
42332f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
42342f514480c448708ec382a684cf5e035d3a827ec8John McCall
42352f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
42369257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        HandleDelayedAccessCheck(diag, decl);
42372f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
4238f85e193739c953358c865005855253af4f68a497John McCall
4239f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
42409257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        handleDelayedForbiddenType(*this, diag, decl);
4241f85e193739c953358c865005855253af4f68a497John McCall        break;
424254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
424354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
42449257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  } while ((pool = pool->getParent()));
42452f514480c448708ec382a684cf5e035d3a827ec8John McCall}
42462f514480c448708ec382a684cf5e035d3a827ec8John McCall
42472f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
42482f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
42490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
42502f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
4251c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    // A category implicitly has the availability of the interface.
4252c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4253c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis      return CatD->getClassInterface()->isDeprecated();
42542f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
42552f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
42562f514480c448708ec382a684cf5e035d3a827ec8John McCall}
42572f514480c448708ec382a684cf5e035d3a827ec8John McCall
42589c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
42592f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
42602f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
42612f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
42622f514480c448708ec382a684cf5e035d3a827ec8John McCall
42632f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4264ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
4265c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
4266ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
4267ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
4268b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  else if (DD.getUnknownObjCClass()) {
4269b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_fwdclass_message)
4270b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian      << DD.getDeprecationDecl()->getDeclName();
4271b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class);
4272b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  }
4273c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
4274c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
4275ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
427654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
427754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
42785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
42798e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
428089ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
428154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4282eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
4283b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
4284b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              UnknownObjCClass,
4285b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              Message));
428654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
428754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
428854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
428954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
42903a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
429154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4292d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian  if (!Message.empty()) {
4293c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
4294c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
4295d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian    Diag(D->getLocation(),
4296d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian         isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
4297d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian                                : diag::note_previous_decl) << D->getDeclName();
4298d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian  }
42998e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
4300743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
43018e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
430289ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
43038e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
430489ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
430589ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
43068e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
430754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4308