SemaDeclAttr.cpp revision 0e78afbb15c6f51932e562e620f714c37cf914e6
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//                     The LLVM Compiler Infrastructure
46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source
66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details.
76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//  This file implements decl-related attribute processing.
116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h"
1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h"
166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h"
17384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
18b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski#include "clang/AST/DeclTemplate.h"
19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
20acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
21f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h"
22fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2319510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
25fe98da0fa352462c02db037360788748f95466f7John McCall#include "clang/Sema/Lookup.h"
26797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
289c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
30883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of
31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
32b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskienum AttributeDeclKind {
33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunction,
34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedUnion,
35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableOrFunction,
36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionOrMethod,
37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameter,
38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrBlock,
39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrParameter,
40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClass,
41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariable,
42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedMethod,
43db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  ExpectedVariableFunctionOrLabel,
44f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor  ExpectedFieldOrGlobalVar,
45f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor  ExpectedStruct
46883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall};
47883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall
48e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
49e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
5287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D,
53a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
5587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
63bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
656217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
66755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
68d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
69183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
723568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
75d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
76a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
7787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) {
7887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return getFunctionType(D, false) != NULL;
79a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
82d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
8487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) {
8587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isFunction(D)|| isa<ObjCMethodDecl>(D);
86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
88620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
9187c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
9287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isFunctionOrMethod(D))
93620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
9587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
9987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<BlockDecl>(D);
100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
101620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
102711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
10487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) {
105f85e193739c953358c865005855253af4f68a497John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
10687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
10787c44604325578b8de07d768391c1c9432404f5aChandler Carruth         isa<ObjCPropertyDecl>(D);
108711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
110d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
111d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
112620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
11387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) {
11487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
11572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
116620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
11787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
118d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
119d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
1203568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1213568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
122d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
123d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
12587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) {
12687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
12772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
12887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
129d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
13087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_size();
1313568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
13487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
13572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
13687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
137d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
1403568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1413568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
14287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) {
14387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
1445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
14587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->getResultType();
1465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
14887c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) {
14987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D)) {
15072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
15287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
153db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
154d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
15587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    return cast<ObjCMethodDecl>(D)->isVariadic();
1563568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
15987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) {
16087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
16107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
16207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
166183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
167b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
169bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
170506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
171506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
174506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
175bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
181085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1826217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
183085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
184085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1866217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
187085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
189bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
191465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
192085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
197b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May
198b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
1991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
2001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth                                  unsigned int Num) {
2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (Attr.getNumArgs() != Num) {
2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    return false;
2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  }
2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  return true;
2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth}
2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
209db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
210b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May
211b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
212b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                  unsigned int Num) {
214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (Attr.getNumArgs() < Num) {
215db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
216db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return false;
217db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  return true;
220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski///
223fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var
224fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable
225fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
22639997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) {
227fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (isa<FieldDecl>(D))
228fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return true;
22939997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const VarDecl *vd = dyn_cast<VarDecl>(D))
230fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
231fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
232fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
235b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool.
236b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) {
237b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = Exp->getType();
238b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return QT->isBooleanType() || QT->isIntegerType();
239b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
240b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
241fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
242fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type.
243fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message.
244fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise
245fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
246ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
247ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                       const AttributeList &Attr) {
24839997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
249fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
25039997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer    if (QT->isAnyPointerType())
251fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
252ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
253fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
254fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
255fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
256fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
257fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
258fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
261b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points
262b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit.
2637d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) {
2647d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const RecordType *RT = QT->getAs<RecordType>())
265b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return RT;
2667d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2677d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  // Now check if we point to record type.
2687d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const PointerType *PT = QT->getAs<PointerType>())
2697d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer    return PT->getPointeeType()->getAs<RecordType>();
2707d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2717d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  return 0;
272b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
273b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
2743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType
275ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// resolves to a lockable object.
27683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchinsstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
27783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins                                   QualType Ty) {
27883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  const RecordType *RT = getRecordType(Ty);
27983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins
28083cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  // Warn if could not get record type for this argument.
281d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT) {
282ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
28383cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      << Attr.getName() << Ty.getAsString();
28483cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
286634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  // Don't check for lockable if the class hasn't been defined yet.
287634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  if (RT->isIncompleteType())
28883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
28983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  // Warn if the type is not lockable.
290d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT->getDecl()->getAttr<LockableAttr>()) {
291ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
29283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      << Attr.getName() << Ty.getAsString();
29383cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
2943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
297b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
298ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// from Sidx, resolve to a lockable object.
2993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with.
3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function
3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list.
302ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
3033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         const AttributeList &Attr,
3043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         SmallVectorImpl<Expr*> &Args,
305b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
306b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
3073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
308b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
3093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
310ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    if (ArgExp->isTypeDependent()) {
311ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // FIXME -- need to check this again on template instantiation
312ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      Args.push_back(ArgExp);
313ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      continue;
314ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    }
315b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
316ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    if (isa<StringLiteral>(ArgExp)) {
317ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // We allow constant strings to be used as a placeholder for expressions
318ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // that are not valid C++ syntax, but warn that they are ignored.
319ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
320ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins        Attr.getName();
321ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      continue;
322ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    }
323ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins
3243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
325b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
328b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
332b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
333b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
334b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
335b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
3363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
3373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
3383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
339b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
340b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
341ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins          continue;
342b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
3433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
344b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
345b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
346b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
34783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    checkForLockableRecord(S, D, Attr, ArgTy);
348b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
350b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
351b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
352b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
353e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
354e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
355e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
356e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
3573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
3583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
3593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
3603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
361fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
362fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
363fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
364fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
365fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
366fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
367fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
368fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
369fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
370fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
371b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
372fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
373fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
374fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
375ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
376fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
377fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
378fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
379768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
380fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
381768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
382fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
383fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
384db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
385b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
387db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
388b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
389db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
392db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
393db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
394b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
395db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
396db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
397db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
398ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
399db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
400db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
401ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  SmallVector<Expr*, 1> Args;
402ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // check that all arguments are lockable objects
403ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
404ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  unsigned Size = Args.size();
405ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size != 1)
406ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
407ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr *Arg = Args[0];
408b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
409db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
410768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
4113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 S.Context, Arg));
412db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
413768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
414db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
415db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
416db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
418fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
419fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
420fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
421fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
422fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
423fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4241748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
425fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
427fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
428fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
432768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
434768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
440fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
444b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
446fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
449fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
450768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
451fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
452fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
453fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
45471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D,
455ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                      const AttributeList &Attr) {
45671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  assert(!Attr.isInvalid());
45771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
45871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!checkAttributeNumArgs(S, Attr, 0))
45971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
46071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
46171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
46271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
46371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany      << Attr.getName() << ExpectedFunctionOrMethod;
46471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
46571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  }
46671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
46771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
46871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany                                                          S.Context));
46971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany}
47071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
471db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
472db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
473db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
474db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
475b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
476db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
477db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
478db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
479b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
480b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
482b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
483db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
485db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
486ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that this attribute only applies to lockable types.
487b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
488b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
489b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
490b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
491ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
492b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
493b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
494b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
495b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
496b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
498ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that all arguments are lockable objects.
499ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
5003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
501ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
502ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
503ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
5043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
505db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
506768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
5073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                    StartArg, Size));
508db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
509768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
5103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                   StartArg, Size));
511db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
512db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
514b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
515db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
516db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
517db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
518db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
519b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
520b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
521db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
522db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
525db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
526b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
528ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
5293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
532db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
533768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
5343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
5353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
537768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
5383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        S.Context, StartArg,
5393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        Size));
540db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
541db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
542db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
543b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
544db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
545db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
546b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
547db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
549b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
550db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
551db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
554db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
555b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
556b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
557b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
558b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
559b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
560b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 2> Args;
562b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
563ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
5643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
568768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
5693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              S.Context,
57069f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                              Attr.getArg(0),
5713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              StartArg, Size));
572db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
573768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
57469f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           S.Context,
57569f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           Attr.getArg(0),
57669f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           StartArg, Size));
577db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
579db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
580b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
583b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
586b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
587db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
591db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
592b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
594ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
5953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
596ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
597ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
598ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
5993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
600db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
601768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
6023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            S.Context, StartArg,
6033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            Size));
604db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
605768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
6063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         S.Context, StartArg,
6073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         Size));
608db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
609db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
610db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
611b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
612db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
613db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
614db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
615db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
616b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
617db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
620db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
621db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
622b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
624ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
6253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
628768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
6293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
630db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
631db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
633b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
634db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
635db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
636b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
637db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
6383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
639db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
640b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
641db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
645db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
647b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
648b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
65083cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  checkForLockableRecord(S, D, Attr, Arg->getType());
6513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
652768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg));
653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
656b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
657db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
658db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
659b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
660db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
661db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
662b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
663db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
664db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
666db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
667db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
668b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
670ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
6713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
672ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
673ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
674ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
6753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
676768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
6773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
678db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
679db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
680db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
6821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
68387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
684545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
685803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
686545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
688bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
6909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
6929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
6949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
695f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
696e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    SourceLocation TemplateKWLoc;
697f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
698f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
6994ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
700e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id,
701e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                          false, false);
7024ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
7034ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
7044ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
7054ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
7069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
7079cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
7081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
7099cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
7101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
7117a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7139cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7149cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
7159cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
7169ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
7179cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
718ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
719a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
720bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7219cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
7229cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
7236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
7281731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
730bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
73187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
732768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
73387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
7356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
7366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
737803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
738fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
73908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
7406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
741768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
7426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
7433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
7446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
74787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
748768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
749c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
750c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
751c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
752c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
7531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
75496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
7551731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
75696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
757bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
75863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
75987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
76063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
761768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
76263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
76363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
76463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7654ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
76663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
76763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7682f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
7692f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // The IBOutlet/IBOutletCollection attributes only apply to instance
7702f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // variables or properties of Objective-C classes.  The outlet must also
7712f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // have an object reference type.
7722f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
7732f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
7740bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
7752f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << VD->getType() << 0;
7762f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
7772f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
7782f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7792f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
7802f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
781f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
7822f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << PD->getType() << 1;
7832f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
7842f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
7852f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7862f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else {
7872f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
7882f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    return false;
7892f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
790f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
7912f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  return true;
7922f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek}
7932f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
7941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
79563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
7961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
79763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
7982f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
7992f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
80063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
80163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8022f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
80396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
80496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
8051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
8061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
807857e918a8a40deb128840308a318bf623d68295fTed Kremenek
808857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
809a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
810857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
811857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
812857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
813857e918a8a40deb128840308a318bf623d68295fTed Kremenek
8142f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
815857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
8162f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
817a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
818a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
819f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian    II = &S.Context.Idents.get("NSObject");
8203a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
821b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
82287c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
823a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
824a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
825a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
826a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
827b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
828a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
829a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
830a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
831a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
832f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
833a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
834a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
835a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
836f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
837f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
838857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
839857e918a8a40deb128840308a318bf623d68295fTed Kremenek
840d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
84168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
84268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
84368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
84468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
84568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
84668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
84768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
84868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
84968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
85068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
85168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
85268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
85368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
85468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
8551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
856bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
857bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
85887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
859fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
860883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
861eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
862eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
86407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
86507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
86687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
86787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
868eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
869eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
8705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
871bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
872eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
873eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
874bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
875bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
876eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
8777a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
878eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
879ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
880ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
881fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
882fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
883eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
884eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
885bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
886eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
887bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
888eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
889fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
89030bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
891eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
892eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
893bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
894465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
89507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
89607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
89707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
89807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
89907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
90007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
90107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
90207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
90307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
904eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
905eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
90687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
907d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
90868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
909dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
910eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
911c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
912fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
9137fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
914eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
915bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
916eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
917eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
918bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
919bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
920bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
9217fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
92287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
92387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
924d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
925dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
926d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
92746bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
928bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
929ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
93060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
93160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
93260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
93360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
93460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
9357fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
93660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
937eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
9387fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
9397fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
9407fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
941dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
942768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
943cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
944eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
945eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
9461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
947dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
948dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
949dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
950dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
951dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
952dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
9532a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
9542a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
955dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
956dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
959dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
960dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
961dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
962cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
9632a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
9642a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
965cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
966dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
967dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
968dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
969dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9702a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9712a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
972cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
973dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
974dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
975dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
976dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9772a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9782a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
979cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
980dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
981dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
982dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
983dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9852a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9862a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
9872a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
9882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
989dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
990dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
99187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
992883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
993883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
994dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
995dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
99707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
99807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
99987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
100087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10025f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1004dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10085f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
1009dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10102a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
10112a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1012dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10137a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1014dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1015dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1016dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1019dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1020dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1021dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1022dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1023dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1024dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1025dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1026dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1027dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
103007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
103107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
103207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
103307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
103407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
103507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
103607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
103707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
103807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1040cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1041cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1042dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
104387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1044dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1045dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1046dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1047cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1048dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1049dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1052dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1053dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1054cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1055dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1056dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
10577a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1058dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1059dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1060dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1061dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1062dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1063dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1064dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1065dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1066dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1067dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1068dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1069dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1070dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1072cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
107387c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
107487c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1075cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1076cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1077cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1078cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1079cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1080cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1081cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1082dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1083dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1084dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1085dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1086dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1087dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1088dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1089dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1090dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1091dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1092cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1093cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1094cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1095cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1096dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1097cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
109887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1099cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1100dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1101dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1102332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1103332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1104332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1105332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1106332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1107332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1108332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1109332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1110332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1111332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1112332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1113332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1114332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1115332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1116332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1117332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1118332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
111911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
112011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
112211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
112311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
112411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
112511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
112611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
112711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
112887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1129332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1130883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1131332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1132332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1133332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
113487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1135332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
113611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
113711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
113811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
113911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
114011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
114111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
114211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
114311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
114411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
114511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
114687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
11477a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
11487a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1149332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
11507a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
115211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
115711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
115811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
115911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
116011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
116111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
116211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
116411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
116611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1171332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1172332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
117311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
117411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
117711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
117811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
118011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
11817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
118211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
118311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
118411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11855cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
118611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
118711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
118811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
118911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
119011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
119111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1192768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1193f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
119411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
119511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1196768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
119711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
119811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
12006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1201545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
12023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12067a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
12076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
12086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1209bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12105cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1211fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12123c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
12136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1215bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1216bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1217f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1218f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1219f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1220f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
12216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1223768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1224f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
12256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1228dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
12291731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1230dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1231dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
123287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1233dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1234883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1235dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1236dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1237dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1238768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1239dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1240dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
12411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
12421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1243dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1244831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
12453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1246af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1247af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
12485bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
124987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
12505bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1251883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
12525bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
12535bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1254bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1255768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1256af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1257af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
12581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1259dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1260831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
126176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
126276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
126376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
12641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
126587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
12672cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1268768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
12692cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
12702cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1271fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1272fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
12732cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
127476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
127576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
12761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
127734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
12781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
127934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
128034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1281768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
128234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
128334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
12841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
128556aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
128687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1287768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1288722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1289722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1290883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1291a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1292a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
129456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
129587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1296768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1297722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1298722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1299883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1300a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1301a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
13021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
130387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1305711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
130787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1308711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1309883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1310711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1311711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1312711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1313768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1314711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1315711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1316711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1317831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1318711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1319711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1320711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1321711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1322711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1323711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1324b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1325b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
13271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1328b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1329b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1330b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1331b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13321731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
13331731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1334b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
133587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
133687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
13373ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
13383ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1339e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1340e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1341b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1342883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1343b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
134419c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
13456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1346b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1347768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
13486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
135035cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
13511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
135235cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
135335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
135435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1355f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1356f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1357f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1358f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1359f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
136035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
136135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
136235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
136335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
136435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
136635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
136735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
136835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
136935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
137035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
137135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
137235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
137335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
137435cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
137587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
137635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1377883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
137835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
137935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
138035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
138187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
138235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
138335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
138435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
138535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
138687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
138701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
138801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
138901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
139001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
139101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
139201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
139301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
139401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
139501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
139601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
139701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
139801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1399f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1400f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
140101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
140201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
140301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
140401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
140501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
140601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
140701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1408768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
140935cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
141035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
14111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
141287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1413bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1414883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1415bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1416bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1417bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1418bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1419bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
14201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
142173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1422831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
142473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
142573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1426bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
142787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
142887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1429fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1430883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
143173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
143273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1433bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1434768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
143573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
143673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1437f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1438f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1439f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1440f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1441f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1442f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1443f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1444f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1445f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1446f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1447f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1448f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1449f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1450f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1451f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1452f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1453f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
14541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1455b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1456831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1457b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1458b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1459b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1460bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
146187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1462186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1463b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1464b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1465b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
146687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1467b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1468883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1469b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1470b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1471bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1472768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1473b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1474b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
14751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1477bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1478bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1480bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14847a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1486ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1487ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1488fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
14903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
14913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
14923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
14933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1494bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
149587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1496fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1497883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
14983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
14993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1501768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1502f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
15033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1507bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1508bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
15093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1510bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
15133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
15147a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
15153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1516ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1517ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1518fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
15203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1524bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
152587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1526fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1527883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1531768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1532f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
15333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1536951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1537951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1538bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1539c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1540c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1541951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1542c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
15435f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1544951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1545951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1546c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1547951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1548951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1549c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1550c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1551951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
15526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1553bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1554768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str));
15556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1558951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1559951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1560bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1561bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1562bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1563951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1564c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
15655f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1566951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1567951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1568c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1569951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1570c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1571c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1572c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1573951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1574c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1575768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str));
1576bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1577bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1578742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1579742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1580742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1581742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1582742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1583742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1584742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1585742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1586742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1587768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1588742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1589742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1590b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beardstatic void handleObjCRootClassAttr(Sema &S, Decl *D,
1591b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard                                    const AttributeList &Attr) {
1592b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (!isa<ObjCInterfaceDecl>(D)) {
1593b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1594b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1595b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1596b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1597b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  unsigned NumArgs = Attr.getNumArgs();
1598b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (NumArgs > 0) {
1599b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1600b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1601b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1602b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1603b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
1604b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard}
1605b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
160671207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
1607e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                            const AttributeList &Attr) {
1608341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  if (!isa<ObjCInterfaceDecl>(D)) {
1609341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
1610341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    return;
1611341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  }
1612341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian
1613e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1614e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  if (NumArgs > 0) {
1615e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1616e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    return;
1617e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  }
1618e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
161971207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
1620e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                 Attr.getRange(), S.Context));
1621e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian}
1622e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
16231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
16241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
16250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
16260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
16270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
16290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
16300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
16310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
16320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
16330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
16350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
16380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
16390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1640b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
16410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1642c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
16430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
16440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
16453b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Deprecated.Version)) {
16460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
16480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16510a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16520a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
16533b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Obsoleted.Version)) {
16540a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16570a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
16613b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Deprecated.Version <= Obsoleted.Version)) {
16620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
16630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
16650a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1668006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  StringRef Str;
1669006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  const StringLiteral *SE =
1670006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
1671006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  if (SE)
1672006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    Str = SE->getString();
1673006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian
1674768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context,
16750a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
16760a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
16770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1678b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1679006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                IsUnavailable,
1680006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                Str));
16810a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
16820a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
16851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
16866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1687bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16887a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
16896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
16906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1691bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16925cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1693fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
16943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
16956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1697bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16985f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1699cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1700bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1701c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1702cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1703c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1704cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1705c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1706cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
17074188760f6bb20f91c6883dffd89204419f852deeJohn McCall  else if (TypeStr == "protected") {
17084188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // Complain about attempts to use protected visibility on targets
17094188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // (like Darwin) that don't support it.
17104188760f6bb20f91c6883dffd89204419f852deeJohn McCall    if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
17114188760f6bb20f91c6883dffd89204419f852deeJohn McCall      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
17124188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Default;
17134188760f6bb20f91c6883dffd89204419f852deeJohn McCall    } else {
17144188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Protected;
17154188760f6bb20f91c6883dffd89204419f852deeJohn McCall    }
17164188760f6bb20f91c6883dffd89204419f852deeJohn McCall  } else {
171708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
17186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1720bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1721768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type));
17226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
17251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1726d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1727d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
172887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1729883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1730d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1731d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1732d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
173387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
173487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
173587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1736d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1737d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
173887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1739d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
174087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1741d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1742d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1743d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17445f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1745d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1746d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1747d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1748d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1749d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1750d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1751d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1752d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1753d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1754d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1755d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1756d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1757d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1758d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1759d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1760d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
176187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1762d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1763d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1764d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1765f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1766f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1767f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1768f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1769f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1770f85e193739c953358c865005855253af4f68a497John McCall    return;
1771f85e193739c953358c865005855253af4f68a497John McCall  }
1772f85e193739c953358c865005855253af4f68a497John McCall
1773768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
1774f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1775d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1776d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
17781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
17791731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
17800db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1781bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17820db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
17830db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
17840db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
17850db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
17860db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1787bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1788768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
17890db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
17900db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
17911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1792fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
17932b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1794fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1795fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1796162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1797fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1798fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
17996217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1800fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1801fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1802fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1803fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1804f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  else if (!isa<ObjCPropertyDecl>(D)) {
1805f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // It is okay to include this attribute on properties, e.g.:
1806f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1807f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
1808f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1809f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // In this case it follows tradition and suppresses an error in the above
1810f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // case.
18119b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
1812f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  }
1813768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
1814fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1815fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1816bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
18171b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1818f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
18192b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1820f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1821f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1822f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1823f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1824f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1825f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1826f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1827f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1828768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
1829f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1830f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
18311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1832bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1833fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
18343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
18359eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18369eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1837bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18389eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
18393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
18409eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18419eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1842bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1843cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
184492e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
18459eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
18469eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1847fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
18483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
18499eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18509eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1851bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1852768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
18539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
18549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
18551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1856770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1857770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1858bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1859770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1860bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1861bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18623323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
1863770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
18647a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1865770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1866ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1867ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1868fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1870770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1871770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1872bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18733323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
1874fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1875fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1876770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1877770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
18783323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
18793323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
1880770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1881770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
18823323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
1883770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
18847a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1885770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1886ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1887ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1888fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1890770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1891770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1892770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1893bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18943323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
1895770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1896770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1897fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1898fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1899770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1900770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1901770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1902770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
190387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
19043323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
1905897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1906897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1907897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1908897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1909bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1910897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
19113bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1912770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1913bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
191487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1915770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
19163bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1917770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
19182f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1919a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
1920a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    if (!BD->isVariadic()) {
1921a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
1922a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      return;
1923a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    }
192487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
19252f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1926daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
192787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1928f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
19292f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
19303bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
19313bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
19322f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
19332f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1934ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
19352f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1936883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
19372f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
19382f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1939770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1940fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1941883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1942770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1943770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1944768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
1945f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1946770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1947770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
19481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1949026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
19501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1951026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1952026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1953f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1954026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1955883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1956026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1957026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1958bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1959f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1960f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1961f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1962f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1963f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1964f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1965f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1966f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1967f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1968f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1969f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1970f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1971768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
1972026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1973026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
19741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
197687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
197787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19806e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
198187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
198213c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    if (isa<CXXRecordDecl>(D)) {
198313c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
198413c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      return;
198513c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    }
198687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
198787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1988f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1989f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1990f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
199187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1992332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1993332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1994332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
199587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
19966e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19976e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1998bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1999768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
20006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20036e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
20041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
20056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
20076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
20096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
20100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
20110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
20120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
20130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
20140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
2015def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2016bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
201790eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2018def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
2019def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
2020c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2021883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
20226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20236e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20246e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
20256e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
2026768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
20276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
20286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
20301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
20316f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
20321731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
20336f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
20346f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
20366f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
20377a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
20386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
2039ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2040ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
20416f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
20426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
20436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
20446f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
20456f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
20466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
2047768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
2048cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
20496f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
20506f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
20516f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
205317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
20541731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
205517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
205617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
205717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
205817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
20597a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2060797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
206117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
2062797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
206317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
206417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
20651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2066797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
2067bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2068a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2069a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2070a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2071797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2072797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
20731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2074a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2075a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2076a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2077a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2078a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2079a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
2080768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context,
2081f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
208217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
208317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
20846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2087831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
20883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
20896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2091b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
209287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2093b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2094ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2095b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2096768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2097b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
20986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2101232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2102831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
21033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2104232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2105232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2106bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
210787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2108b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2109ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2110b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2111768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2112b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2113232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2114232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
21151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2116232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
21171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2118232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2119bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2120768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2121232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2122232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
21231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2124bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2125f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2126f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2127f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2128bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2129f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2130f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2131f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2132f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2133bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
213487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2135bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2136f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2137f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2138f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2139f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2141f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2142c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2143f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2144f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2145f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2146f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2147f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2148f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2149f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2150f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2152f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2153f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2154f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2155f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2156f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2157f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2158f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2159f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2160f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2161f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2162f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2163f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2164f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2165f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
216789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
216889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
216989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
217089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2171b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2172b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2173f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
217489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
217589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
217689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
217789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2178bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2179768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
21805f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
2181f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2182f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2183bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2184bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
21851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21861731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
21875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21881731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
218987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
21905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2191883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
21925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
219407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
219507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
219607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
219787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
219887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
21995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
220007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
22015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
22027a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
22035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2204ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2205ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
22065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
22075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
22085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2210bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
22125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
22135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
22145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2216bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2218bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
221907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
222007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
222107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
222207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
222307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
222407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
222507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
222607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
222707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
22285b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
222987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2230bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
22325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
22335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22356217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2238bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
22395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2241bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
224287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
22435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
22445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22466217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2249bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
22505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2252bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2253bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2254768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
225507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
22565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
22575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
22582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
22592b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
22602b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
22612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
22622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
22633c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
22642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
22652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
22662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
22682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
22695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
22702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
22712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
22722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
22732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
22742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
22752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
22762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
22772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
22792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
228069d53845c68a4f01920b58ba6ce507d78220689cJean-Daniel Dupas      Format == "strfmon" || Format == "cmn_err" || Format == "vcmn_err" ||
2281cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2282cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
22832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
22842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2285bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2286bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
22873c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
22883c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
22902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
22912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2292521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2293521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
22941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
22951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
22964e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!S.getLangOpts().CPlusPlus) {
2297521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2298521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2299521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2300521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
230187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2302b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2303b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2304b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2305b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
230687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2307b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2308b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2309b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2310b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2311b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2312b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2313b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2314b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2315521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2316521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2317521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2318521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2319521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
23207a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2321b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2322521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2323521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2324521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2325521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2326521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2327521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2328521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2329521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
23309f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2331521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2332521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2333521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2334521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2335521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2336521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2337768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2338f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2339521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2340521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2341bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2342bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
23431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
23446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2345545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2346fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
23473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
23486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2351545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
23523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
23536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
235687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2358883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
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;
23666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
23676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
23696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
23712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
23722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
23732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
23742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
23752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
23763c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23773c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
23783c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
23793c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2381fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
238201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
23836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
23877a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2388803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2389ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2390ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2391fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2397fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
23983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
24036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2404bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24054a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
24064a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
240707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
240807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
240907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
24104a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
24114a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
24124a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
24134a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
24141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
241687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
24176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2419085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2420fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2421fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2422085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2423085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
24242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2425390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2426390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2427803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2428390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2429fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2430fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
24316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2432bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
24336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
24346217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2435390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2436fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2437fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
24386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
24427a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2443803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2444ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2445ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2446fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
24473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
24526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
245387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
24546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
24556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
245687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
24576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
24623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
24632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
24646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2465fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2466fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
24676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
24706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2471fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
24723c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2476b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2477b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
247887c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
247987c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2480b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2481b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2482b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2483b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2484b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2485b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2486b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2487b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2488ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis        f->setRange(Attr.getRange());
2489b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2490b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2491b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2492b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
2493768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format,
2494cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
24952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
24966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
24991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
25006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
25011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
25026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
25060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
250787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
25080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
25090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
25100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
251187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
25120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
25130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2514fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2515883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
25166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25195e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall  if (!RD->isCompleteDefinition()) {
2520bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
25210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
25220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25230c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
25240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
252517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
252617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
25270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
25280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
25290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2531bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
25330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
253490cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2535bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
253690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
253790cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
25380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2540bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
25420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
25430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
25440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
25450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
25460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
25470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
25480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2549bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
25500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2551bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
25520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
25530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
25540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2555bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
25560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
25570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2558bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2559bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2560bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
25616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2562768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
25636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
25671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
25686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25691731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25707a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2571797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2572bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
25746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
25756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2576797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
25776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
257977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
258077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
258177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
258277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
258377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
258477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
258577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
258677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
2587768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
2588f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
25896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2593545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
25943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
25956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2597bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2598bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2599bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2600bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
26016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2602545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2603768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0));
26044ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
26054ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
26064ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2607768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0));
26084ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
26094ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2610768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
26110b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  // FIXME: Handle pack-expansions here.
26120b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  if (DiagnoseUnexpandedParameterPack(E))
26130b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne    return;
26140b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne
26154ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
26164ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2617768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
26186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2620bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2621768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
2622cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
262349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
2624282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  ExprResult ICE =
2625282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith    VerifyIntegerConstantExpression(E, &Alignment,
2626282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith      PDiag(diag::err_attribute_argument_not_int) << "aligned",
2627282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith      /*AllowFold*/ false);
2628282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  if (ICE.isInvalid())
262949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
2630396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
26314ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
26324ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2633396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2634396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2635396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2636282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take()));
2637cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2638cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2639768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
2640cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2641cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2642768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS));
2643cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
26446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2645fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2646d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2647bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2648fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2649bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2650bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2651bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
26521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2653fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2654fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2655fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2656fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
26571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2658fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
26591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2660fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2661fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2662fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
26630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2664fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2665fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2666210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
26675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2668fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2669fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2670210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2671210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2672fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2673fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
267573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2676210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2677fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
267873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
267973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
268073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
268173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
268273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
268373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
268473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
268573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
268673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
268773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
268873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
268973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
269073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
269173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
269273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
269373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2694fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2695fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2696fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2698210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
2699bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2700210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
2701bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
2702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2704210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
2705bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2708fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2710162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2712fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2713fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2714fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2715fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2716768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
2717fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2718fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
271973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2720183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
272173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
272273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
27232ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
272473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
272573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
272673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
272773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
272873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
272973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
273073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
273173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
273273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2733390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2734390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2735390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2736390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2737f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2738f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2739fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2740fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2741fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
27423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2743fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2744fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
27453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2747fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
274873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
274973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
275073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
275173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27530b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2754fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2756fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2757fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
275873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
275973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
276073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
276173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2762fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2764fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2767fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2770fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
27710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2772fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2775fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2776fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2779bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2780aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2781aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2782aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2783fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2784bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2785aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2786aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2787aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2788fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
278973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
279073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
279173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2792f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2793f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2794f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2795f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2796f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2797f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2798f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2799f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2800f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
280173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2802fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2803fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
280473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
280573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2806fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2807fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2808fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2809162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2810ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2811a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2812ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2813fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2814fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
28150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
28161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2817d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
28181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2819d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2820e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
282187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2822d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2823883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2824d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2825d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2827768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
2828d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2829d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
28301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
28315bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
28321731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
28341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2835bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
283687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2838883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
28405bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2841bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2842768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
28435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
28445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
28451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
28461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
28477255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
28481731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28497255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
28517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
285287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2854883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28567255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
28577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2858768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
2859f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
28607255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
28617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
28621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2863ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2864ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2865831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2866ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2867ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2868ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2869ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
287087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2871ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2872883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2873ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2874ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2875ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2876768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
2877ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2878ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2879ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2880ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2881ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2883ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2884ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2885ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2886ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2887ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2888ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2889ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
289087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2891ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2892883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2893ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2894ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2895ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2896768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
2897ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2898ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2899ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2900ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2901ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2903ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2904ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2906ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2907ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
290887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2909ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2910883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2911ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2912ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2913ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
291487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
29152c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2916723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
29172c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
29182c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
29192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
29202c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
29212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
29222c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
29232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
29242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
29252c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
29262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
29272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
29282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2929768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
2930ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2931ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2932ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2933ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2934ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2936ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2937ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2939ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2941ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
294287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2943ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2944883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2945ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2946ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2947ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2948768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
2949ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2950ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2951ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2952ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2953ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2955ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2956ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2958ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2960ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
296187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2962ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2963883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2964ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2965ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2966ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2967768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
2968ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2969ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2970ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2971ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2972ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
297426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
29751731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
297626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2977bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
297887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2979c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
298026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2981883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
298226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
298326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2984bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
29850130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2986cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2987c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2988c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2990768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
299126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
299226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
29931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
299487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2995711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
299687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2997e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2998711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
299987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
3000711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3001e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
300287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
300387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
300487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3005711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3006711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3007711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
300887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3009e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
3010768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
3011e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3012e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
3013768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
3014e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3015f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
3016768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
301704633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
3018e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
3019768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
3020e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
302152fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3022768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
302352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
3024414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
302587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
3026414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30275cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
302887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3029414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
303087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3031414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3032414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3033414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
30345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3035414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
3036414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
3037414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
3038414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
3039414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
3040414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
304187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
304287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3043414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3044414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3045414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
3046768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
3047414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3048e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
3049e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
3050e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
3051e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
3052e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
30531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
305456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
3055768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3056f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
3057f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
3058711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
3059711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
3060711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3061711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3062831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
3063831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
3064831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
3065711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3066711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
3067711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3068ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
306955d3aaf9a537888734762170823daf750ea9036dEli Friedman
3070414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3071414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3072711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
3073711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
3074711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
3075711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
3076711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
3077711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
3078414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
3079414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3080414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30815cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3082414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3083414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3084414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3085414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3086414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3087414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
30885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3089414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3090414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3091414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3092414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3093414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3094414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3095414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3096414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3097414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
30987530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("unexpected attribute kind");
3099711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3100711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3101711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3102711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
31041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
310587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3106711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3107711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
310887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3110711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
311187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
311287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
311387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3114ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3115ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
311655d3aaf9a537888734762170823daf750ea9036dEli Friedman
3117768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3118711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3119711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3120711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3121711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
312287c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
312387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3124711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3125711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
312687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
312787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
312887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3129711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3130711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3131711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
313287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
313355d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3134ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3135711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
313687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
313755d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
313887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3139711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
314055d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
314155d3aaf9a537888734762170823daf750ea9036dEli Friedman
3142bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
314387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
314455d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
314587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3146711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
314755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
314855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3149711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3150bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
315187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3152bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
315387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3154711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
315555d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
315655d3aaf9a537888734762170823daf750ea9036dEli Friedman
3157711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3158ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3159ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
31601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
31617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
31627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
31637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3164bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3165bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
31667b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31677b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
316987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
31707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3171883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
31727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
31767b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
31777b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
31787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
31797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
31807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
31827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
31867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
31877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
31887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
31897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
31907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
31917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
31937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
31947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
31957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3197768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
31987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
31997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
32007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
32017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
32027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
32037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
32047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
32050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3206b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3207b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3208b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3209c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
32106c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
32116c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isObjCObjectPointerType() ||
32126c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         S.Context.isObjCNSObjectType(type);
3213c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3214c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
32156c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
32166c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isPointerType() ||
32176c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         isValidSubjectOfNSAttribute(S, type);
3218c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3219c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
322187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3222c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
322387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3224768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3225c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3226c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3227c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3228c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
322987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3230c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3231c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3232c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3233c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3234c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3235c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3236c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3237c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
323887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3239768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3240c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3241c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3242c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3243c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3244768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3245c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3246768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3247c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3248c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
32501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
325187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
325287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3253768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3254c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3255c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3256c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3257768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3258c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3259c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
32611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3262b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3263c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3264bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
326587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3266c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
326787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3268831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
32694e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
327087c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3271f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
327287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3273c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
32745dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
327587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3276768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3277883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3278b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3279b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3280bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3281c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3282c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
328387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
32847530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("invalid ownership attribute");
3285c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3286c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3287c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3288c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3289c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3290c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3291c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3292c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3293c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3294c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3295c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3296c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3297c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3298c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3299c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
330087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3301768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3302bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
33035dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3304bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
330587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3306b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3307b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
3308c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
3309768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3310c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3311c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
331231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
3313768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3314f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
331531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
331631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
3317768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3318f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
331931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3320b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
3321768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3322f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3323b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3324b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
3325768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3326f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3327b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3328b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3329b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3330b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3331dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3332dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3333dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3334dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3335dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3336dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
33370e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian  if (!method || !isa<ObjCMethodDecl>(method)) {
33380e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3339f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
3340dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3341dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3342dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3343dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3344dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3345f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian
3346f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3347f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3348dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3349dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3350dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3351dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3352dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3353dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3354dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3355dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3356dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3357768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3358dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3359dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
33608dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
33618dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
33628dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
33638dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3364f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << A.getRange() << A.getName() << ExpectedFunction;
33658dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33668dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33678dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33688dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer);
33698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33708dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
33718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
33728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
33748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
33768dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
33788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
33798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
33808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
33818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
33828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
33868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
33888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
33898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
33918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
33928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
33948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3395fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
3396fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
3397fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
3398fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
3399fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3400f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedStruct;
3401fe98da0fa352462c02db037360788748f95466f7John McCall  }
3402fe98da0fa352462c02db037360788748f95466f7John McCall
3403fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
3404fe98da0fa352462c02db037360788748f95466f7John McCall
3405fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
3406fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
3407fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
34084e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (ParmName && S.getLangOpts().ObjC1) {
3409fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
3410fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
3411fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
3412fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
3413fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
3414fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
3415fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
3416fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
3417fe98da0fa352462c02db037360788748f95466f7John McCall      }
3418fe98da0fa352462c02db037360788748f95466f7John McCall    }
3419fe98da0fa352462c02db037360788748f95466f7John McCall  }
3420fe98da0fa352462c02db037360788748f95466f7John McCall
3421fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
3422fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
3423fe98da0fa352462c02db037360788748f95466f7John McCall}
3424fe98da0fa352462c02db037360788748f95466f7John McCall
34251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
34261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
342787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3428f85e193739c953358c865005855253af4f68a497John McCall
342987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3430f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    << Attr.getRange() << Attr.getName() << ExpectedVariable;
3431f85e193739c953358c865005855253af4f68a497John McCall}
3432f85e193739c953358c865005855253af4f68a497John McCall
34331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
34341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
343587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
343687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3437f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedVariable;
3438f85e193739c953358c865005855253af4f68a497John McCall    return;
3439f85e193739c953358c865005855253af4f68a497John McCall  }
3440f85e193739c953358c865005855253af4f68a497John McCall
344187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3442f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3443f85e193739c953358c865005855253af4f68a497John McCall
3444f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3445f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
344687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3447f85e193739c953358c865005855253af4f68a497John McCall      << type;
3448f85e193739c953358c865005855253af4f68a497John McCall    return;
3449f85e193739c953358c865005855253af4f68a497John McCall  }
3450f85e193739c953358c865005855253af4f68a497John McCall
3451f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3452f85e193739c953358c865005855253af4f68a497John McCall
3453f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3454f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3455f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3456f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3457f85e193739c953358c865005855253af4f68a497John McCall
3458f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3459f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3460f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3461f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3462f85e193739c953358c865005855253af4f68a497John McCall    break;
3463f85e193739c953358c865005855253af4f68a497John McCall
3464f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3465f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3466f85e193739c953358c865005855253af4f68a497John McCall    break;
3467f85e193739c953358c865005855253af4f68a497John McCall
3468f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3469f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
347087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3471f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3472f85e193739c953358c865005855253af4f68a497John McCall    break;
3473f85e193739c953358c865005855253af4f68a497John McCall  }
3474f85e193739c953358c865005855253af4f68a497John McCall
347587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3476768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3477f85e193739c953358c865005855253af4f68a497John McCall}
3478f85e193739c953358c865005855253af4f68a497John McCall
3479f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
34809428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  switch (Attr.getKind()) {
34819428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  default:
34829428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return false;
34839428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllimport:
34849428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllexport:
34859428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_uuid:
34869428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_deprecated:
34879428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noreturn:
34889428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_nothrow:
34899428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_naked:
34909428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noinline:
34919428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return true;
34929428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  }
349311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
349411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
349511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
349611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
349711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
349811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
34991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
350062ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
350111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
35021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
350311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
35041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
350511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
350611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
35075cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3508d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3509d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3510d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3511d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3512d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
35135f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3514d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3515d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3516d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3517f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
3518d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3519d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3520d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3521d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3522d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3523d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3524d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3525d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3526d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3527d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3528f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3529d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
35305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3531f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3532f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3533f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3534f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3535d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3536d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3537d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3538d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3539d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3540d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3541d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3542d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3543d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3544d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3545d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
354611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
3547768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
354811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3549d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
355011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3551f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3552f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3553b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
35540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
35550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
35560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
35571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
355960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
35601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
35611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
35621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
356360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
356460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
356560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
356660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3567e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
35681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3570803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
3571e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_ibaction:            handleIBAction(S, D, Attr); break;
3572e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutlet:          handleIBOutlet(S, D, Attr); break;
3573e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutletcollection:
35741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3575803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3576207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3577ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
35786e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
35794211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
35804211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3581bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3582bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3583803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
358460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
358560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
358660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
358760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
358860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
358960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
35901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
35911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3592bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
35931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3594b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
35951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
35961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
35971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3598bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
35991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
36001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
36011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
36021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
36031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
36041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
36053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
36061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
36073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
36081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
36091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
36101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
36111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
36127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
36131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
36147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
36151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
36161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
36171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
36181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
36191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3620dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3621dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3622dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
36231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
36241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
36251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
36261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
36271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
36281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3629b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3630b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
36311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3632f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
36331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3634f85e193739c953358c865005855253af4f68a497John McCall
3635dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3636dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3637dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3638fe98da0fa352462c02db037360788748f95466f7John McCall  case AttributeList::AT_ns_bridged:
3639fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
3640fe98da0fa352462c02db037360788748f95466f7John McCall
36418dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_audited_transfer:
36428dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_unknown_transfer:
36438dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
36448dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3645b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3646c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
36471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3648c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
36491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3650c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3651c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
365231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
365331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3654b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3655b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
36561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3657b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3658e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_reqd_work_group_size:
36591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
36606f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3661521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
36621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3663521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
36641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
3665e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_ms_struct:    handleMsStructAttr    (S, D, Attr); break;
36661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
36671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3668e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_objc_arc_weak_reference_unavailable:
3669742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3670742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
3671b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  case AttributeList::AT_objc_root_class:
3672b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    handleObjCRootClassAttr(S, D, Attr);
3673b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    break;
367471207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  case AttributeList::AT_objc_requires_property_definitions:
367571207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
3676e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    break;
36771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
3678f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  case AttributeList::AT_returns_twice:
3679f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
3680f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
36811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
36821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
36831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3684026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
36851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
36861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
36871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3688803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
36891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3690803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
36910db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
36921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
36930db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3694d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
36951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3696d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
3697e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_NSObject:    handleObjCNSObject    (S, D, Attr); break;
36981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
36991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
37001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
37011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
37021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
37031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
37041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
37051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3706bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
370705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
370805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
37097255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
37101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
37117255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
371204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
371304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
371404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3715f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
371652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3717414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
37181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
371904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3720f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
37211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3722f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
372311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
37241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
372511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3726fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3727fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3728fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3729fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3730fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3731fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3732fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3733fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3734fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3735fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3736fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
373771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  case AttributeList::AT_no_address_safety_analysis:
373871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    handleNoAddressSafetyAttr(S, D, Attr);
373971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    break;
3740fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3741fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3742fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3743fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3744fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3745fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3746db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3747db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3748db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3749db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3750db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3751db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3752db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3753db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3754db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3755db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3756db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3757db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3758db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3759db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3760db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3761db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3762db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3763db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3764db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3765db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3766db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3767db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3768db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3769db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3770db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3771db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3772db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3773db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3774db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3775db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3776db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3777db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3778db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3779db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3780db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3781db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3782db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3783db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3784db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3785fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3786803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
378782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
378882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
378982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
37907d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
37917d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3792803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3793803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3794803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3795803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
379660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
379760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
379860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
379960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
38001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
38011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
380260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
380360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
380460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
380560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
380660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
380760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
380860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
380960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
381060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
38111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
381260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
381360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
38141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
381560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
381660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3817803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3818803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3819f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
382060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
382160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
382211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
38231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
382411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
382511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
382611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
382711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
382811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
382960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
383011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3831dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
383211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3833803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3834803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3835803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
38365f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access
38375f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier.
38385f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
38395f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          const AttributeList *AttrList) {
38405f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
38415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    if (l->getKind() == AttributeList::AT_annotate) {
38425f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      handleAnnotateAttr(*this, ASDecl, *l);
38435f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    } else {
38445f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
38455f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      return true;
38465f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    }
38475f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  }
38485f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
38495f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  return false;
38505f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen}
38515f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
3852e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
3853e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
3854e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
3855e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
3856e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
3857e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
3858e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
3859e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3860e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
3861e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
3862e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3863e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
3864e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
3865e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3866e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
3867e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
3868e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3869e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3870e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
3871e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
3872e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
3873e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
3874e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
3875e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
3876e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
3877e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
3878e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3879e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3880e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3881e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
3882900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
3883900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
38847b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3885e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3886e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3887900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
3888900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
3889900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
3890900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
3891900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
3892900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3893900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
3894900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
3895900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
3896900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
3897900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
3898900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
3899900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
3900900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3901900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
3902c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3903900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3904900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
3905900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
3906900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
3907900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
3908900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
3909900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
3910900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
3911900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
3912900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
3913900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
3914900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
39154278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
3916b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3917e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3918e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3919ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3920a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
392116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
392216573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3923b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3924b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3925c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3926b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3927e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3928e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3929e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3930e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3931e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3932e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
39337b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3934c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3935c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3936c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3937c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3938900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
3939cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3940cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3941cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3942c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3943c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3944c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3945c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3946c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3947c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3948c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3949c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3950cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3951e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3952e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3953e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
39540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
39550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
39560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
395760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
395860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3959d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3960d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
396131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
396231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
396331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
396431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
396531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
396631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
396731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
396831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
396931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
397031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
397131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
397231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3973d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3974e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3975e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3976e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3977e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
39780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
39797f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
398060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3981bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
39820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
39830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
39840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
39850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
39860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
39870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
398860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
39900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
39910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
399260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
39930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
399454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3995f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3996f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3997f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3998f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3999f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
4000a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
4001a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
4002a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
4003f85e193739c953358c865005855253af4f68a497John McCall    return false;
4004f85e193739c953358c865005855253af4f68a497John McCall
4005f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
4006f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
4007f85e193739c953358c865005855253af4f68a497John McCall}
4008f85e193739c953358c865005855253af4f68a497John McCall
4009f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
4010f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4011f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
4012f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
4013f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
4014f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
4015f85e193739c953358c865005855253af4f68a497John McCall    return;
4016f85e193739c953358c865005855253af4f68a497John McCall  }
40174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (S.getLangOpts().ObjCAutoRefCount)
4018175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
4019175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // FIXME. we may want to supress diagnostics for all
4020175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // kind of forbidden type messages on unavailable functions.
4021175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
4022175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag.getForbiddenTypeDiagnostic() ==
4023175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
4024175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
4025175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
4026175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
4027175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
4028f85e193739c953358c865005855253af4f68a497John McCall
4029f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4030f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4031f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
4032f85e193739c953358c865005855253af4f68a497John McCall}
4033f85e193739c953358c865005855253af4f68a497John McCall
4034eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
4035eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
4036eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
4037eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
4038eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4039eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
4040eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
4041eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
4042eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
4043eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
4044eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4045eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
4046eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
4047eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4048eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
4049eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
4050eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
4051eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
4052eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4053eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
4054eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
405554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
405654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4057eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
4058eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
4059eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
406054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4061eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
4062eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
4063eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
4064eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
406554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4066eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
4067eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
406854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4069eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
4070eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
4071eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
407258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
40732f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
40742f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
4075e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall  if (decl) {
4076eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
4077eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
40782f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
40792f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
40802f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
40812f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
40822f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
4083eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
4084eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
4085eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
40862f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
40872f514480c448708ec382a684cf5e035d3a827ec8John McCall
4088eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
40892f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
4090e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        // Don't bother giving deprecation diagnostics if the decl is invalid.
4091e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        if (!decl->isInvalidDecl())
4092e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall          S.HandleDelayedDeprecationCheck(diag, decl);
40932f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
40942f514480c448708ec382a684cf5e035d3a827ec8John McCall
40952f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
4096eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
40972f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
4098f85e193739c953358c865005855253af4f68a497John McCall
4099f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
4100f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
4101f85e193739c953358c865005855253af4f68a497John McCall        break;
410254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
410354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
410454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
410554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
410658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
4107eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
410829233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
410958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
4110eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
41112f514480c448708ec382a684cf5e035d3a827ec8John McCall}
41122f514480c448708ec382a684cf5e035d3a827ec8John McCall
41132f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
41142f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
41150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
41162f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
4117c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    // A category implicitly has the availability of the interface.
4118c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4119c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis      return CatD->getClassInterface()->isDeprecated();
41202f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
41212f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
41222f514480c448708ec382a684cf5e035d3a827ec8John McCall}
41232f514480c448708ec382a684cf5e035d3a827ec8John McCall
41249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
41252f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
41262f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
41272f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
41282f514480c448708ec382a684cf5e035d3a827ec8John McCall
41292f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4130ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
4131c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
4132ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
4133ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
4134b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  else if (DD.getUnknownObjCClass()) {
4135b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_fwdclass_message)
4136b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian      << DD.getDeprecationDecl()->getDeclName();
4137b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class);
4138b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  }
4139c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
4140c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
4141ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
414254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
414354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
41445f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
41458e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
414689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
414754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4148eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
4149b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
4150b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              UnknownObjCClass,
4151b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              Message));
415254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
415354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
415454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
415554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
41563a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
415754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4158ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
4159c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
4160c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
41618e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
4162743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
41638e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
416489ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
41658e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
416689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
416789ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
41688e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
416954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4170