SemaDeclAttr.cpp revision 79747e00e9f6b13b56e91462982d2456d0d9128f
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
31679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
31779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      // Ignore empty strings without warnings
31879747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (StrLit->getLength() == 0)
31979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        continue;
32079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
321ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // We allow constant strings to be used as a placeholder for expressions
322ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // that are not valid C++ syntax, but warn that they are ignored.
323ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
324ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins        Attr.getName();
325ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      continue;
326ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    }
327ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins
3283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
329b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
33079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // A pointer to member expression of the form  &MyClass::mu is treated
33179747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // specially -- we need to look at the type of the member.
33279747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
33379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (UOp->getOpcode() == UO_AddrOf)
33479747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
33579747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins          if (DRE->getDecl()->isCXXInstanceMember())
33679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins            ArgTy = DRE->getDecl()->getType();
33779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
3383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
340b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
344b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
345b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
346b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
347b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
3483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
3493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
3503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
351b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
352b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
353ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins          continue;
354b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
3553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
356b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
357b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
358b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
35983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    checkForLockableRecord(S, D, Attr, ArgTy);
360b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
362b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
363b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
364b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
365e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
366e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
367e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
368e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
3693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
3703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
3713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
3723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
373fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
374fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
375fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
376fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
377fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
378fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
379fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
380fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
381fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
382fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
383b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
384fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
385fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
386fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
387ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
388fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
389fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
390fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
391768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
392fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
393768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
394fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
395fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
396db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
397b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
398db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
399db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
400b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
401db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
402db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
403db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
404db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
405db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
406b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
407db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
408db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
409db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
410ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
411db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
412db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
413ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  SmallVector<Expr*, 1> Args;
414ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // check that all arguments are lockable objects
415ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
416ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  unsigned Size = Args.size();
417ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size != 1)
418ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
419ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr *Arg = Args[0];
420b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
421db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
422768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
4233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 S.Context, Arg));
424db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
425768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
426db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
427db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
428db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4361748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
440fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
444768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
446768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
449fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
450fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
451fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
452fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
453fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
454fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
455fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
456b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
457fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
458fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
459fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
460fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
461fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
462768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
463fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
464fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
465fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
46671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D,
467ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                      const AttributeList &Attr) {
46871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  assert(!Attr.isInvalid());
46971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
47071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!checkAttributeNumArgs(S, Attr, 0))
47171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
47271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
47371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
47471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
47571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany      << Attr.getName() << ExpectedFunctionOrMethod;
47671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
47771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  }
47871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
47971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
48071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany                                                          S.Context));
48171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany}
48271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
483db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
485db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
486db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
487b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
488db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
489db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
491b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
492b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
493db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
494b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
495db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
496db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
497db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
498ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that this attribute only applies to lockable types.
499b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
500b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
501b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
502b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
503ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
504b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
505b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
506b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
507b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
508b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
510ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that all arguments are lockable objects.
511ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
5123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
513ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
514ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
515ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
5163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
517db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
518768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
5193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                    StartArg, Size));
520db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
521768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
5223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                   StartArg, Size));
523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
525db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
526b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
527db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
528db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
529db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
530db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
531b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
532b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
533db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
534db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
535db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
537db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
538b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
540ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
5413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
544db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
545768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
5463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
5473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
549768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
5503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        S.Context, StartArg,
5513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        Size));
552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
554db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
555b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
556db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
558b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
559db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
560db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
561b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
562db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
563db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
565db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
566db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
567b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
568b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
569b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
570b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
571b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
572b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 2> Args;
574b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
575ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
5763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
579db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
580768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
5813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              S.Context,
58269f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                              Attr.getArg(0),
5833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              StartArg, Size));
584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
585768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
58669f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           S.Context,
58769f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           Attr.getArg(0),
58869f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           StartArg, Size));
589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
591db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
592b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
593db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
594db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
595b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
596db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
597db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
598b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
599db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
600db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
601db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
602db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
603db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
604b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
606ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
6073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
608ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
609ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
610ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
6113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
612db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
613768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
6143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            S.Context, StartArg,
6153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            Size));
616db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
617768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
6183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         S.Context, StartArg,
6193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         Size));
620db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
621db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
622db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
623b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
624db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
625db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
626db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
627db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
628b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
629db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
630db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
631db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
633db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
634b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
636ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
6373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
640768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
6413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
645b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
646db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
647db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
648b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
6503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
651db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
652b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
656db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
657db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
659b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
660b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
66283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  checkForLockableRecord(S, D, Attr, Arg->getType());
6633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
664768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg));
665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
666db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
667db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
668b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
670db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
671b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
672db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
673db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
674b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
675db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
676db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
677db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
678db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
679db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
680b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
682ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
6833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
684ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
685ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
686ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
6873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
688768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
6893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
690db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
691db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
692db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
6941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
69587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
696545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
697803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
698545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
6996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
700bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
7029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
7049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
7069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
707f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
708e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    SourceLocation TemplateKWLoc;
709f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
710f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
7114ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
712e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id,
713e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                          false, false);
7144ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
7154ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
7164ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
7174ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
7189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
7199cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
7201731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
7219cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
7221731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
7237a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
7246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7259cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
7279cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
7289ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
7299cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
730ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
731a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7339cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
7349cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
7356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
7401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
7416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
742bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
74387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
744768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
74587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
7466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
7476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
7486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
749803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
750fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
75108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
7526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
753768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
7546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
7553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
7566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
75987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
760768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
761c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
762c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
763c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
764c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
7651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
76696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
7671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
76896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
769bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
77063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
77187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
77263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
773768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
77463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
77563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
77663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7774ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
77863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
77963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7802f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
7812f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // The IBOutlet/IBOutletCollection attributes only apply to instance
7822f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // variables or properties of Objective-C classes.  The outlet must also
7832f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // have an object reference type.
7842f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
7852f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
7860bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
7872f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << VD->getType() << 0;
7882f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
7892f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
7902f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7912f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
7922f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
793f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
7942f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << PD->getType() << 1;
7952f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
7962f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
7972f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7982f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else {
7992f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
8002f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    return false;
8012f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
802f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
8032f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  return true;
8042f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek}
8052f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
80763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
8081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
80963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
8102f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8112f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
81263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
81363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8142f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
81596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
81696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
8171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
8181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
819857e918a8a40deb128840308a318bf623d68295fTed Kremenek
820857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
821a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
822857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
823857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
824857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
825857e918a8a40deb128840308a318bf623d68295fTed Kremenek
8262f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
827857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
8282f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
829a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
830a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
831f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian    II = &S.Context.Idents.get("NSObject");
8323a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
833b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
83487c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
835a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
836a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
837a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
838a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
839b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
840a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
841a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
842a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
843a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
844f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
845a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
846a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
847a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
848f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
849f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
850857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
851857e918a8a40deb128840308a318bf623d68295fTed Kremenek
852d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
85368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
85468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
85568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
85668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
85768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
85868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
85968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
86068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
86168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
86268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
86368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
86468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
86568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
86668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
8671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
868bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
869bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
87087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
871fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
872883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
873eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
874eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
875bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
87607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
87707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
87887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
87987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
880eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
881eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
8825f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
883bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
884eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
885eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
886bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
887bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
888eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
8897a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
890eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
891ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
892ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
893fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
894fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
895eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
896eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
897bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
898eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
899bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
900eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
901fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
90230bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
903eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
904eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
905bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
906465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
90707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
90807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
90907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
91007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
91107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
91207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
91307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
91407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
91507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
916eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
917eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
91887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
919d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
92068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
921dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
922eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
923c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
924fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
9257fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
926eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
928eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
929eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
930bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
931bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
932bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
9337fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
93487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
93587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
936d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
937dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
938d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
93946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
940bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
941ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
94260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
94360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
94460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
94560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
94660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
9477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
94860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
949eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
9507fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
9517fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
9527fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
953dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
954768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
955cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
956eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
957eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
9581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
959dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
960dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
961dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
962dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
963dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
964dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
9652a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
9662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
967dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
968dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
969dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
970dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
971dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
972dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
973dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
974cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
9752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
9762a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
977cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
978dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
979dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
980dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
981dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9822a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9832a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
984cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
986dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
987dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
988dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
991cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
992dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
993dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
994dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
995dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9972a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9982a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
9992a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
10002a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1002dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
100387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
1004883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1005883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1008dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
100907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
101007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
101187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
101287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1013dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
1015dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1016dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
1019dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10205f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
1021dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10222a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
10232a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1024dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10257a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1026dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1027dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1030dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1031dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1032dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1033dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1034dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1035dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1036dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1037dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1040dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1041dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
104207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
104307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
104407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
104507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
104607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
104707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
104807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
104907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
105007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1052cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1053cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
105587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1056dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1057dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1058dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1059cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1060dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1061dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1062dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1063dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1064dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1065dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1066cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1067dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1068dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
10697a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1070dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1072dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1073dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1074dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1075dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1077dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1078dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1079dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1080dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1081dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1082dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1083dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1084cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
108587c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
108687c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1087cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1089cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1090cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1091cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1092cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1093cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1094dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1095dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1096dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1097dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1098dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1099dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1100dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1101dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1102dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1103dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1104cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1105cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1106cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1107cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1108dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1109cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
111087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1111cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1112dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1113dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1114332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1115332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1116332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1117332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1118332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1119332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1120332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1121332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1122332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1123332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1124332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1125332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1126332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1127332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1128332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1129332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1130332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
113111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
113211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
113411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
113511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
113611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
113711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
113811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
113911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
114087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1141332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1142883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1143332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1144332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1145332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
114687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1147332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
114811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
114911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
115011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
115211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
115711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
115887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
11597a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
11607a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1161332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
11627a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
116411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
116611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
117111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
117311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
117411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
117711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
117811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
118011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
118111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
118211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1183332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1184332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
118511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
118611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
118711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
118811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
118911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
119011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
119111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
119211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
11937a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
119411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
119511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
119611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11975cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
119811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
119911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
120011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
120111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
120211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
120311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1204768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1205f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
120611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
120711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1208768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
120911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
121011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
12111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
12126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1213545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
12143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1217bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
12196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
12206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1221bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12225cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1223fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12243c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
12256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1227bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1228bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1229f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1230f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1231f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1232f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
12336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1235768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1236f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
12376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1240dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
12411731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1242dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1243dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
124487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1245dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1246883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1247dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1248dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1249dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1250768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1251dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1252dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
12531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
12541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1255dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1256831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
12573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1258af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1259af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
12605bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
126187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
12625bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1263883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
12645bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
12655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1266bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1267768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1268af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1269af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
12701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1271dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1272831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
127376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
127476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
127576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
12761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
127787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
12792cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1280768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
12812cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
12822cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1283fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1284fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
12852cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
128676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
128776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
12881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
128934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
12901731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
129134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
129234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1293768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
129434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
129534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
12961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
129756aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
129887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1299768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1300722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1301722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1302883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1303a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1304a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
13051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
130656aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
130787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1308768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1309722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1310722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1311883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1312a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1313a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
13141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
131587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1316711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1317711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1318711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
131987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1320711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1321883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1322711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1323711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1324711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1325768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1326711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1327711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1328711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1329831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1330711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1331711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1332711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1333711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1334711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1335711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1336b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1337b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
13391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1340b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1341b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1342b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1343b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
13451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1346b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
134787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
134887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
13493ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
13503ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1351e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1352e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1353b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1354883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1355b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
135619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
13576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1358b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1359768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
13606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
136235cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
13631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
136435cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
136635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1367f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1368f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1369f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1370f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1371f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
137235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
137435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
137635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
137735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
137835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
137935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
138035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
138135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
138235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
138335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
138435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
138535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
138635cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
138787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
138835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1389883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
139035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
139135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
139235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
139387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
139435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
139535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
139635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
139735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
139887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
139901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
140001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
140101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
140201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
140301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
140401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
140501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
140601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
140701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
140801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
140901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
141001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1411f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1412f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
141301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
141401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
141501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
141601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
141701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
141801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
141901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1420768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
142135cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
142235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
14231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
142487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1425bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1426883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1427bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1428bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1429bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1430bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1431bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
14321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
143373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1434831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
143673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
143773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1438bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
143987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
144087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1441fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1442883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
144373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
144473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1445bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1446768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
144773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
144873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1449f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1450f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1451f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1452f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1453f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1454f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1455f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1456f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1457f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1458f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1459f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1460f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1461f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1462f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1463f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1464f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1465f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
14661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1467b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1468831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1469b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1470b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1471b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1472bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
147387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1474186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1475b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1476b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1477b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
147887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1479b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1480883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1481b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1482b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1483bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1484768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1485b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1486b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
14871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1489bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1490bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1492bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1498ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1499ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1500fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
15023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1506bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
150787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1508fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1509883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1513768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1514f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
15153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1519bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1520bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
15213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1522bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
15253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
15267a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
15273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1528ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1529ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1530fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
15323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1536bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
153787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1538fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1539883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1543768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1544f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
15453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1548951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1549951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1550bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1551c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1552c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1553951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1554c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
15555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1556951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1557951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1558c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1559951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1560951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1561c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1562c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1563951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
15646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1565bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1566768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str));
15676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1570951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1571951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1572bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1573bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1574bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1575951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1576c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
15775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1578951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1579951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1580c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1581951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1582c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1583c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1584c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1585951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1586c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1587768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str));
1588bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1589bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1590742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1591742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1592742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1593742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1594742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1595742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1596742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1597742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1598742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1599768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1600742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1601742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1602b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beardstatic void handleObjCRootClassAttr(Sema &S, Decl *D,
1603b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard                                    const AttributeList &Attr) {
1604b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (!isa<ObjCInterfaceDecl>(D)) {
1605b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1606b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1607b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1608b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1609b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  unsigned NumArgs = Attr.getNumArgs();
1610b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (NumArgs > 0) {
1611b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1612b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1613b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1614b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1615b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
1616b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard}
1617b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
161871207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
1619e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                            const AttributeList &Attr) {
1620341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  if (!isa<ObjCInterfaceDecl>(D)) {
1621341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
1622341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    return;
1623341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  }
1624341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian
1625e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1626e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  if (NumArgs > 0) {
1627e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1628e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    return;
1629e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  }
1630e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
163171207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
1632e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                 Attr.getRange(), S.Context));
1633e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian}
1634e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
16351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
16361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
16370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
16380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
16390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16405f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
16410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
16420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
16430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
16440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
16450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
16470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
16500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
16510a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1652b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
16530a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1654c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
16550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
16560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
16573b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Deprecated.Version)) {
16580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
16600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16610a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
16653b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Obsoleted.Version)) {
16660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16680a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16690a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16700a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16710a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16720a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
16733b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Deprecated.Version <= Obsoleted.Version)) {
16740a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
16750a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16760a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
16770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16790a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1680006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  StringRef Str;
1681006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  const StringLiteral *SE =
1682006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
1683006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  if (SE)
1684006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    Str = SE->getString();
1685006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian
1686768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context,
16870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
16880a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
16890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1690b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1691006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                IsUnavailable,
1692006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                Str));
16930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
16940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
16971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
16986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1699bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17007a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
17016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
17026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1703bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17045cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1705fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
17063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
17076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1709bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1711cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1712bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1713c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1714cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1715c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1716cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1717c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1718cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
17194188760f6bb20f91c6883dffd89204419f852deeJohn McCall  else if (TypeStr == "protected") {
17204188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // Complain about attempts to use protected visibility on targets
17214188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // (like Darwin) that don't support it.
17224188760f6bb20f91c6883dffd89204419f852deeJohn McCall    if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
17234188760f6bb20f91c6883dffd89204419f852deeJohn McCall      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
17244188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Default;
17254188760f6bb20f91c6883dffd89204419f852deeJohn McCall    } else {
17264188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Protected;
17274188760f6bb20f91c6883dffd89204419f852deeJohn McCall    }
17284188760f6bb20f91c6883dffd89204419f852deeJohn McCall  } else {
172908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
17306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1733768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type));
17346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
17371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1738d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1739d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
174087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1741883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1742d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1743d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1744d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
174587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
174687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
174787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1748d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1749d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
175087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1751d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
175287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1753d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1754d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1755d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1757d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1758d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1759d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1760d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1761d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1762d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1763d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1764d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1765d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1766d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1767d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1768d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1769d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1770d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1771d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1772d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
177387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1774d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1775d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1776d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1777f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1778f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1779f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1780f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1781f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1782f85e193739c953358c865005855253af4f68a497John McCall    return;
1783f85e193739c953358c865005855253af4f68a497John McCall  }
1784f85e193739c953358c865005855253af4f68a497John McCall
1785768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
1786f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1787d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1788d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
17901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
17911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
17920db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1793bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17940db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
17950db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
17960db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
17970db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
17980db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1799bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1800768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
18010db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
18020db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
18031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1804fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
18052b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1806fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1807fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1808162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1809fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1810fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
18116217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1812fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1813fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1814fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1815fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1816f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  else if (!isa<ObjCPropertyDecl>(D)) {
1817f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // It is okay to include this attribute on properties, e.g.:
1818f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1819f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
1820f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1821f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // In this case it follows tradition and suppresses an error in the above
1822f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // case.
18239b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
1824f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  }
1825768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
1826fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1827fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1828bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
18291b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1830f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
18312b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1832f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1833f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1834f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1835f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1836f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1837f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1838f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1839f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1840768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
1841f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1842f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
18431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1844bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1845fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
18463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
18479eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18489eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1849bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18509eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
18513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
18529eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1854bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1855cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
185692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
18579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
18589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1859fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
18603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
18619eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1864768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
18659eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
18669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
18671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1868770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1869770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1870bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1871770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1872bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1873bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18743323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
1875770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
18767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1877770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1878ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1879ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1880fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1882770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1883770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1884bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18853323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
1886fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1887fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1888770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1889770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
18903323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
18913323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
1892770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1893770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
18943323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
1895770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
18967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1897770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1898ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1899ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1900fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
19013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1902770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1903770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1904770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1905bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19063323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
1907770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1908770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1909fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1910fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1911770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1912770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1913770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1914770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
191587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
19163323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
1917897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1918897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1919897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1920897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1921bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1922897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
19233bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1924770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1925bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
192687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1927770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
19283bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1929770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
19302f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1931a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
1932a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    if (!BD->isVariadic()) {
1933a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
1934a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      return;
1935a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    }
193687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
19372f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1938daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
193987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1940f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
19412f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
19423bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
19433bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
19442f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
19452f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1946ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
19472f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1948883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
19492f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
19502f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1951770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1952fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1953883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1954770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1955770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1956768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
1957f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1958770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1959770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
19601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1961026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
19621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1963026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1964026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1965f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1966026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1967883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1968026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1969026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1970bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1971f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1972f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1973f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1974f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1975f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1976f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1977f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1978f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1979f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1980f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1981f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1982f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1983768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
1984026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1985026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
19861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
198887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
198987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
199387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
199413c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    if (isa<CXXRecordDecl>(D)) {
199513c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
199613c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      return;
199713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    }
199887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
199987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
2000f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
2001f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
2002f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
200387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
2004332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
2005332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
2006332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
200787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
20086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
2010bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2011768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
20126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
20161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
20176e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
20196e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20206e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
20216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
20220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
20230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
20240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
20250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
20260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
2027def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2028bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
202990eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2030def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
2031def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
2032c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2033883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
20346e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
20376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
2038768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
20396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
20406e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
20421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
20436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
20441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
20456f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
20466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20476f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
20486f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
20497a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
20506f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
2051ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2052ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
20536f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
20546f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
20556f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
20566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
20576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
20586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
2059768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
2060cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
20616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
20626f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
20636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
206517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
20661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
206717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
206817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
206917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
207017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
20717a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2072797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
207317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
2074797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
207517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
207617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
20771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2078797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
2079bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2080a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2081a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2082a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2083797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2084797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
20851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2086a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2087a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2088a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2089a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2090a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2091a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
2092768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context,
2093f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
209417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
209517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
20966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2099831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
21003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
21016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2103b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
210487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2105b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2106ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2107b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2108768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2109b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
21106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
21116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2113232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2114831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
21153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2116232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2117232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2118bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
211987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2120b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2121ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2122b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2123768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2124b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2125232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2126232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
21271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2128232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
21291731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2130232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2131bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2132768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2133232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2134232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
21351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2136bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2137f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2138f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2139f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2141f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2142f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2143f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2144f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2145bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
214687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2147bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2148f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2149f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2150f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2151f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2152bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2153f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2154c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2155f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2156f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2157f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2158f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2159f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2160f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2161f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2162f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2163bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2164f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2165f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2166f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2167f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2168f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2169f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2170f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2171f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2172f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2173f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2174f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2175f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2176f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2177f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2178bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
217989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
218089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
218189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
218289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2183b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2184b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2185f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
218689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
218789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
218889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
218989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2191768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
21925f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
2193f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2194f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2195bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
21971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
21995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
220187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
22025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2203883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22055b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
220607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
220707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
220807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
220987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
221087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
22115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
221207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
22135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
22147a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
22155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2216ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2217ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
22185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
22195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
22205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
22245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
22255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
22265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2228bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2230bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
223107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
223207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
223307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
223407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
223507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
223607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
223707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
223807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
223907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
22405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
224187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2242bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
22445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
22455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22476217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
22515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2253bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
225487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
22555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
22565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22586217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2261bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
22625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2264bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2265bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2266768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
226707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
22685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
22695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
22702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
22712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
22722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
22732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
22742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
22753c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
22762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
22772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
22782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
22802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
22815f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
22822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
22832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
22842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
22852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
22862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
22872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
22882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
22892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
22912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
229269d53845c68a4f01920b58ba6ce507d78220689cJean-Daniel Dupas      Format == "strfmon" || Format == "cmn_err" || Format == "vcmn_err" ||
2293cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2294cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
22952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
22962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2297bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2298bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
22993c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
23003c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
23022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
23032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2304521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2305521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
23061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
23071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
23084e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!S.getLangOpts().CPlusPlus) {
2309521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2310521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2311521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2312521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
231387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2314b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2315b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2316b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2317b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
231887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2319b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2320b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2321b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2322b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2323b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2324b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2325b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2326b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2327521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2328521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2329521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2330521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2331521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
23327a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2333b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2334521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2335521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2336521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2337521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2338521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2339521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2340521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2341521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
23429f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2343521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2344521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2345521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2346521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2347521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2348521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2349768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2350f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2351521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2352521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2353bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2354bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
23551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
23566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2357545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2358fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
23593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
23606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2363545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
23643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
23656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
236887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2369fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2370883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
237407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
237507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
237687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
237787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
23786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
23796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
23816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
23832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
23842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
23852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
23862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
23872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
23883c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23893c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
23903c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
23913c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2393fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
239401eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
23956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
23997a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2400803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2401ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2402ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2403fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
24043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
24056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2409fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
24103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
24116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
24156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2416bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24174a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
24184a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
241907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
242007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
242107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
24224a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
24234a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
24244a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
24254a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
24261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
242887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
24296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2431085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2432fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2433fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2434085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2435085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
24362b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2437390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2438390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2439803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2440390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2441fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2442fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
24436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2444bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
24456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
24466217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2447390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2448fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2449fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
24506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
24547a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2455803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2456ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2457ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2458fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
24593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
24646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
246587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
24666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
24676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
246887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
24696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
24743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
24752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
24766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2477fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2478fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
24796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
24826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2483fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
24843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2488b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2489b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
249087c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
249187c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2492b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2493b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2494b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2495b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2496b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2497b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2498b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2499b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2500ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis        f->setRange(Attr.getRange());
2501b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2502b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2503b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2504b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
2505768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format,
2506cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
25072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
25086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
25111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
25126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
25131731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
25146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25151731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
25180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
251987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
25200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
25210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
25220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
252387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
25240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
25250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2526fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2527883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
25286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25315e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall  if (!RD->isCompleteDefinition()) {
2532bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
25330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
25340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
25360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
253717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
253817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
25390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
25400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
25410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2543bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
25450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
254690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2547bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
254890cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
254990cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
25500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2552bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
25540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
25550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
25560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
25570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
25580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
25590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
25600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2561bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
25620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2563bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
25640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
25650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
25660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2567bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
25680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
25690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2570bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2571bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2572bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
25736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2574768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
25756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
25791731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
25806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25811731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25827a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2583797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2584bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
25866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
25876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2588797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
25896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
259177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
259277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
259377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
259477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
259577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
259677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
259777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
259877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
2599768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
2600f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
26016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
26026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
26046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2605545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
26063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
26076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2609bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2610bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2611bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2612bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
26136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2614545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2615768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0));
26164ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
26174ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
26184ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2619768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0));
26204ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
26214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2622768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
26230b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  // FIXME: Handle pack-expansions here.
26240b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  if (DiagnoseUnexpandedParameterPack(E))
26250b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne    return;
26260b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne
26274ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
26284ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2629768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
26306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2632bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2633768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
2634cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
263549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
2636282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  ExprResult ICE =
2637282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith    VerifyIntegerConstantExpression(E, &Alignment,
2638282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith      PDiag(diag::err_attribute_argument_not_int) << "aligned",
2639282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith      /*AllowFold*/ false);
2640282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  if (ICE.isInvalid())
264149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
2642396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
26434ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
26444ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2645396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2646396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2647396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2648282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take()));
2649cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2650cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2651768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
2652cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2653cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2654768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS));
2655cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
26566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2657fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2658d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2659bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2660fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2661bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2662bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2663bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
26641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2665fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2666fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2667fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2668fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
26691731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2670fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
26711731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2672fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2673fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
26750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2676fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2677fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2678210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
26795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2680fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2681fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2682210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2683210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2684fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2685fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2686fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
268773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2688210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2689fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
269073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
269173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
269273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
269373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
269473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
269573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
269673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
269773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
269873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
269973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
270073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
270173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
270273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
270373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
270473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
270573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2708fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2710210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
2711bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2712210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
2713bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
2714fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2715fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2716210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
2717bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2718fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2719fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2720fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2721fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2722162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2723fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2724fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2725fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2726fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2727fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2728768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
2729fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2730fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
273173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2732183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
273373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
273473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
27352ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
273673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
273773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
273873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
273973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
274073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
274173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
274273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
274373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
274473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2745390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2746390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2747390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2748390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2749f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2750f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2751fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2753fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
27543c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2755fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2756fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
27573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2758fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
276073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
276173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
276273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
276373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2764fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
277073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
277173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
277273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
277373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2776fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2779fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2780fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
27830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2784fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2786fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2787fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2788fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2790fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2791bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2792aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2793aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2794aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2795fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2796bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2797aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2798aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2799aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2800fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
280173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
280273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
280373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2804f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2805f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2806f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2807f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2808f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2809f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2810f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2811f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2812f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
281373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2814fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2815fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
281673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
281773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2818fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2819fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2820fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2821162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2822ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2823a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2824ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2825fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2826fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
28270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
28281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2829d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
28301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2831d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2832e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
283387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2834d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2835883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2836d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2837d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2838bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2839768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
2840d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2841d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
28421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
28435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
28441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
28461731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2847bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
284887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28495bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2850883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28515bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
28525bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2853bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2854768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
28555bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
28565bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
28571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
28581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
28597255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
28601731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
28637255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
286487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28657255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2866883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28677255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28687255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
28697255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2870768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
2871f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
28727255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
28737255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
28741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2875ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2876ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2877831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2878ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2879ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2880ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2881ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
288287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2883ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2884883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2885ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2886ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2887ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2888768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
2889ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2890ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2891ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2892ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2893ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2895ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2896ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2897ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2898ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2899ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2900ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2901ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
290287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2903ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2904883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2905ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2906ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2907ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2908768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
2909ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2910ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2911ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2912ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2913ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2915ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2916ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2918ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2919ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
292087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2921ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2922883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2923ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2924ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2925ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
292687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
29272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2928723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
29292c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
29302c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
29312c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
29322c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
29332c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
29342c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
29352c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
29362c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
29372c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
29382c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
29392c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
29402c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2941768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
2942ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2943ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2944ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2945ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2946ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2948ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2949ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2951ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2953ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
295487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2955ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2956883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2957ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2958ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2959ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2960768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
2961ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2962ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2963ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2964ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2965ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2967ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2968ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29691731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2970ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29711731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2972ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
297387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2974ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2975883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2976ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2977ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2978ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2979768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
2980ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2981ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2982ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2983ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2984ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
298626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
29871731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
298826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
299087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2991c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
299226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2993883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
299426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
299526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2996bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
29970130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2998cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2999c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
3000c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
3001bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3002768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
300326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
300426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
30051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
300687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3007711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
300887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
3009e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3010711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
301187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
3012711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3013e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
301487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
301587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
301687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3017711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3018711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3019711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
302087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3021e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
3022768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
3023e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3024e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
3025768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
3026e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3027f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
3028768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
302904633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
3030e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
3031768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
3032e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
303352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3034768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
303552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
3036414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
303787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
3038414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30395cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
304087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3041414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
304287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3043414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3044414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3045414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
30465f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3047414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
3048414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
3049414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
3050414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
3051414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
3052414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
305387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
305487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3055414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3056414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3057414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
3058768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
3059414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3060e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
3061e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
3062e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
3063e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
3064e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
30651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
306656aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
3067768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3068f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
3069f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
3070711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
3071711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
3072711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3073711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3074831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
3075831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
3076831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
3077711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3078711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
3079711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3080ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
308155d3aaf9a537888734762170823daf750ea9036dEli Friedman
3082414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3083414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3084711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
3085711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
3086711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
3087711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
3088711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
3089711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
3090414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
3091414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3092414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30935cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3094414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3095414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3096414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3097414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3098414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3099414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
31005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3101414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3102414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3103414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3104414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3105414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3106414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3107414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3108414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3109414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
31107530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("unexpected attribute kind");
3111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3112711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3113711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3114711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3115711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
31161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
311787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3118711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3119711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
312087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3121711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3122711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
312387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
312487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
312587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3126ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3127ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
312855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3129768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3130711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3131711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3132711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3133711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
313487c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
313587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3136711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3137711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
313887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
313987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
314087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3141711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3142711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3143711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
314487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
314555d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3146ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3147711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
314887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
314955d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
315087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3151711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
315255d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
315355d3aaf9a537888734762170823daf750ea9036dEli Friedman
3154bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
315587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
315655d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
315787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3158711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
315955d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
316055d3aaf9a537888734762170823daf750ea9036dEli Friedman
3161711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3162bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
316387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3164bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
316587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3166711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
316755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
316855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3169711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3170ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3171ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
31721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
31737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
31747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
31757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3176bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3177bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
31787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
318187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
31827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3183883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
31847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
31887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
31897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
31907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
31917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
31927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
31947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
31987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
31997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
32007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
32017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
32027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
32037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
32047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
32057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
32067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
32077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
32087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3209768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
32107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
32117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
32127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
32137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
32147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
32157b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
32167b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
32170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3218b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3219b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3220b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3221c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
32226c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
32236c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isObjCObjectPointerType() ||
32246c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         S.Context.isObjCNSObjectType(type);
3225c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3226c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
32276c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
32286c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isPointerType() ||
32296c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         isValidSubjectOfNSAttribute(S, type);
3230c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3231c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
323387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3234c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
323587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3236768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3237c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3238c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3239c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3240c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
324187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3242c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3243c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3244c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3245c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3246c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3247c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3248c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3249c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
325087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3251768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3252c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3253c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3254c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3255c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3256768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3257c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3258768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3259c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3260c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
32621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
326387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
326487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3265768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3266c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3267c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3268c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3269768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3270c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3271c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
32731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3274b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3275c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3276bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
327787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3278c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
327987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3280831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
32814e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
328287c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3283f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
328487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3285c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
32865dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
328787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3288768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3289883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3290b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3291b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3292bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3293c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3294c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
329587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
32967530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("invalid ownership attribute");
3297c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3298c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3299c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3300c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3301c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3302c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3303c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3304c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3305c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3306c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3307c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3308c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3309c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3310c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3311c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
331287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3313768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3314bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
33155dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3316bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
331787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3318b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3319b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
3320c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
3321768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3322c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3323c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
332431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
3325768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3326f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
332731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
332831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
3329768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3330f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
333131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3332b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
3333768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3334f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3335b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3336b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
3337768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3338f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3339b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3340b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3341b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3342b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3343dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3344dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3345dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3346dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3347dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3348dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
334994d55d7ecdd693788a8f3910a0da1b5ecdaa8a86Fariborz Jahanian  if (!method) {
33500e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3351f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
3352dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3353dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3354dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3355dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3356dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3357f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian
3358f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3359f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3360dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3361dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3362dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3363dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3364dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3365dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3366dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3367dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3368dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3369768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3370dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3371dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
33728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
33738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
33748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
33758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3376f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << A.getRange() << A.getName() << ExpectedFunction;
33778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer);
33818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
33838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
33848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
33868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
33888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
33908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
33918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
33928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
33938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
33948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
33988dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
34008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
34018dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
34028dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
34038dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
34048dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
34058dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
34068dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3407fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
3408fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
3409fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
3410fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
3411fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3412f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedStruct;
3413fe98da0fa352462c02db037360788748f95466f7John McCall  }
3414fe98da0fa352462c02db037360788748f95466f7John McCall
3415fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
3416fe98da0fa352462c02db037360788748f95466f7John McCall
3417fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
3418fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
3419fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
34204e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (ParmName && S.getLangOpts().ObjC1) {
3421fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
3422fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
3423fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
3424fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
3425fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
3426fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
3427fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
3428fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
3429fe98da0fa352462c02db037360788748f95466f7John McCall      }
3430fe98da0fa352462c02db037360788748f95466f7John McCall    }
3431fe98da0fa352462c02db037360788748f95466f7John McCall  }
3432fe98da0fa352462c02db037360788748f95466f7John McCall
3433fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
3434fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
3435fe98da0fa352462c02db037360788748f95466f7John McCall}
3436fe98da0fa352462c02db037360788748f95466f7John McCall
34371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
34381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
343987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3440f85e193739c953358c865005855253af4f68a497John McCall
344187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3442f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    << Attr.getRange() << Attr.getName() << ExpectedVariable;
3443f85e193739c953358c865005855253af4f68a497John McCall}
3444f85e193739c953358c865005855253af4f68a497John McCall
34451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
34461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
344787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
344887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3449f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedVariable;
3450f85e193739c953358c865005855253af4f68a497John McCall    return;
3451f85e193739c953358c865005855253af4f68a497John McCall  }
3452f85e193739c953358c865005855253af4f68a497John McCall
345387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3454f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3455f85e193739c953358c865005855253af4f68a497John McCall
3456f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3457f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
345887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3459f85e193739c953358c865005855253af4f68a497John McCall      << type;
3460f85e193739c953358c865005855253af4f68a497John McCall    return;
3461f85e193739c953358c865005855253af4f68a497John McCall  }
3462f85e193739c953358c865005855253af4f68a497John McCall
3463f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3464f85e193739c953358c865005855253af4f68a497John McCall
3465f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3466f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3467f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3468f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3469f85e193739c953358c865005855253af4f68a497John McCall
3470f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3471f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3472f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3473f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3474f85e193739c953358c865005855253af4f68a497John McCall    break;
3475f85e193739c953358c865005855253af4f68a497John McCall
3476f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3477f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3478f85e193739c953358c865005855253af4f68a497John McCall    break;
3479f85e193739c953358c865005855253af4f68a497John McCall
3480f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3481f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
348287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3483f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3484f85e193739c953358c865005855253af4f68a497John McCall    break;
3485f85e193739c953358c865005855253af4f68a497John McCall  }
3486f85e193739c953358c865005855253af4f68a497John McCall
348787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3488768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3489f85e193739c953358c865005855253af4f68a497John McCall}
3490f85e193739c953358c865005855253af4f68a497John McCall
3491f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
34929428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  switch (Attr.getKind()) {
34939428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  default:
34949428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return false;
34959428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllimport:
34969428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllexport:
34979428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_uuid:
34989428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_deprecated:
34999428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noreturn:
35009428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_nothrow:
35019428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_naked:
35029428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noinline:
35039428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return true;
35049428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  }
350511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
350611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
350711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
350811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
350911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
351011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
35111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
351262ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
351311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
35141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
351511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
35161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
351711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
351811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
35195cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3520d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3521d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3522d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3523d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3524d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
35255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3526d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3527d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3528d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3529f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
3530d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3531d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3532d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3533d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3534d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3535d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3536d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3537d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3538d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3539d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3540f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3541d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
35425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3543f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3544f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3545f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3546f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3547d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3548d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3549d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3550d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3551d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3552d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3553d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3554d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3555d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3556d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3557d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
355811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
3559768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
356011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3561d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
356211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3563f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3564f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3565b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
35660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
35670744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
35680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
35691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
357160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
35721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
35731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
35741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
357560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
357660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
357760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
357860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3579e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
35801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3582803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
3583e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_ibaction:            handleIBAction(S, D, Attr); break;
3584e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutlet:          handleIBOutlet(S, D, Attr); break;
3585e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutletcollection:
35861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3587803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3588207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3589ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
35906e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
35914211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
35924211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3593bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3594bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3595803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
359660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
359760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
359860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
359960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
360060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
360160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
36021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
36031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3604bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
36051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3606b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
36071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
36081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
36091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3610bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
36111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
36121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
36131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
36141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
36151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
36161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
36173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
36181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
36193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
36201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
36211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
36221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
36231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
36247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
36251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
36267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
36271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
36281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
36291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
36301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
36311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3632dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3633dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3634dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
36351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
36361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
36371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
36381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
36391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
36401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3641b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3642b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
36431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3644f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
36451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3646f85e193739c953358c865005855253af4f68a497John McCall
3647dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3648dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3649dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3650fe98da0fa352462c02db037360788748f95466f7John McCall  case AttributeList::AT_ns_bridged:
3651fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
3652fe98da0fa352462c02db037360788748f95466f7John McCall
36538dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_audited_transfer:
36548dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_unknown_transfer:
36558dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
36568dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3657b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3658c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
36591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3660c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
36611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3662c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3663c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
366431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
366531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3666b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3667b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
36681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3669b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3670e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_reqd_work_group_size:
36711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
36726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3673521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
36741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3675521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
36761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
3677e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_ms_struct:    handleMsStructAttr    (S, D, Attr); break;
36781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
36791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3680e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_objc_arc_weak_reference_unavailable:
3681742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3682742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
3683b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  case AttributeList::AT_objc_root_class:
3684b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    handleObjCRootClassAttr(S, D, Attr);
3685b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    break;
368671207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  case AttributeList::AT_objc_requires_property_definitions:
368771207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
3688e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    break;
36891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
3690f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  case AttributeList::AT_returns_twice:
3691f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
3692f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
36931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
36941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
36951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3696026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
36971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
36981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
36991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3700803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
37011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3702803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
37030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
37041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
37050db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3706d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
37071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3708d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
3709e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_NSObject:    handleObjCNSObject    (S, D, Attr); break;
37101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
37111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
37121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
37131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
37141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
37151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
37161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
37171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3718bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
371905f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
372005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
37217255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
37221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
37237255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
372404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
372504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
372604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3727f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
372852fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3729414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
37301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
373104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3732f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
37331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3734f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
373511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
37361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
373711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3738fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3739fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3740fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3741fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3742fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3743fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3744fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3745fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3746fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3747fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3748fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
374971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  case AttributeList::AT_no_address_safety_analysis:
375071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    handleNoAddressSafetyAttr(S, D, Attr);
375171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    break;
3752fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3753fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3754fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3755fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3756fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3757fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3758db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3759db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3760db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3761db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3762db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3763db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3764db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3765db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3766db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3767db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3768db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3769db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3770db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3771db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3772db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3773db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3774db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3775db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3776db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3777db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3778db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3779db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3780db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3781db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3782db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3783db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3784db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3785db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3786db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3787db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3788db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3789db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3790db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3791db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3792db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3793db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3794db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3795db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3796db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3797fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3798803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
379982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
380082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
380182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
38027d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
38037d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3804803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3805803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3806803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3807803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
380860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
380960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
381060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
381160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
38121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
38131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
381460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
381560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
381660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
381760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
381860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
381960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
382060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
382160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
382260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
38231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
382460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
382560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
38261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
382760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
382860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3829803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3830803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3831f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
383260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
383360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
383411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
38351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
383611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
383711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
383811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
383911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
384011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
384160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
384211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3843dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
384411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3845803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3846803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3847803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
38485f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access
38495f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier.
38505f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
38515f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          const AttributeList *AttrList) {
38525f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
38535f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    if (l->getKind() == AttributeList::AT_annotate) {
38545f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      handleAnnotateAttr(*this, ASDecl, *l);
38555f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    } else {
38565f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
38575f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      return true;
38585f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    }
38595f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  }
38605f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
38615f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  return false;
38625f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen}
38635f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
3864e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
3865e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
3866e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
3867e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
3868e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
3869e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
3870e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
3871e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3872e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
3873e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
3874e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3875e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
3876e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
3877e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3878e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
3879e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
3880e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3881e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3882e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
3883e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
3884e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
3885e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
3886e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
3887e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
3888e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
3889e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
3890e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3891e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3892e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3893e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
3894900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
3895900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
38967b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3897e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3898e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3899900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
3900900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
3901900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
3902900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
3903900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
3904900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3905900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
3906900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
3907900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
3908900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
3909900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
3910900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
3911900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
3912900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3913900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
3914c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3915900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3916900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
3917900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
3918900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
3919900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
3920900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
3921900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
3922900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
3923900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
3924900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
3925900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
3926900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
39274278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
3928b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3929e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3930e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3931ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3932a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
393316573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
393416573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3935b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3936b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3937c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3938b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3939e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3940e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3941e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3942e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3943e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3944e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
39457b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3946c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3947c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3948c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3949c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3950900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
3951cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3952cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3953cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3954c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3955c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3956c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3957c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3958c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3959c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3960c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3961c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3962cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3963e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3964e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3965e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
39660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
39670744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
39680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
396960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
397060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3971d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3972d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
397331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
397431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
397531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
397631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
397731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
397831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
397931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
398031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
398131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
398231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
398331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
398431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3985d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3986e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3987e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3988e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3989e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
39900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
39917f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
399260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3993bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
39940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
39950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
39960744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
39970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
39980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
39990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
400060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4001bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
40020744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
40030744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
400460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
40050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
400654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4007f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
4008f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
4009f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
4010f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
4011f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
4012a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
4013a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
4014a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
4015f85e193739c953358c865005855253af4f68a497John McCall    return false;
4016f85e193739c953358c865005855253af4f68a497John McCall
4017f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
4018f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
4019f85e193739c953358c865005855253af4f68a497John McCall}
4020f85e193739c953358c865005855253af4f68a497John McCall
4021f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
4022f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4023f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
4024f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
4025f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
4026f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
4027f85e193739c953358c865005855253af4f68a497John McCall    return;
4028f85e193739c953358c865005855253af4f68a497John McCall  }
40294e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (S.getLangOpts().ObjCAutoRefCount)
4030175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
4031175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // FIXME. we may want to supress diagnostics for all
4032175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // kind of forbidden type messages on unavailable functions.
4033175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
4034175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag.getForbiddenTypeDiagnostic() ==
4035175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
4036175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
4037175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
4038175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
4039175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
4040f85e193739c953358c865005855253af4f68a497John McCall
4041f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4042f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4043f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
4044f85e193739c953358c865005855253af4f68a497John McCall}
4045f85e193739c953358c865005855253af4f68a497John McCall
4046eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
4047eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
4048eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
4049eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
4050eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4051eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
4052eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
4053eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
4054eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
4055eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
4056eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4057eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
4058eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
4059eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4060eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
4061eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
4062eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
4063eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
4064eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4065eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
4066eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
406754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
406854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4069eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
4070eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
4071eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
407254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4073eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
4074eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
4075eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
4076eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
407754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4078eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
4079eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
408054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4081eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
4082eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
4083eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
408458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
40852f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
40862f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
4087e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall  if (decl) {
4088eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
4089eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
40902f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
40912f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
40922f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
40932f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
40942f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
4095eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
4096eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
4097eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
40982f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
40992f514480c448708ec382a684cf5e035d3a827ec8John McCall
4100eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
41012f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
4102e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        // Don't bother giving deprecation diagnostics if the decl is invalid.
4103e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        if (!decl->isInvalidDecl())
4104e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall          S.HandleDelayedDeprecationCheck(diag, decl);
41052f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
41062f514480c448708ec382a684cf5e035d3a827ec8John McCall
41072f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
4108eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
41092f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
4110f85e193739c953358c865005855253af4f68a497John McCall
4111f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
4112f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
4113f85e193739c953358c865005855253af4f68a497John McCall        break;
411454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
411554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
411654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
411754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
411858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
4119eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
412029233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
412158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
4122eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
41232f514480c448708ec382a684cf5e035d3a827ec8John McCall}
41242f514480c448708ec382a684cf5e035d3a827ec8John McCall
41252f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
41262f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
41270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
41282f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
4129c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    // A category implicitly has the availability of the interface.
4130c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4131c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis      return CatD->getClassInterface()->isDeprecated();
41322f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
41332f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
41342f514480c448708ec382a684cf5e035d3a827ec8John McCall}
41352f514480c448708ec382a684cf5e035d3a827ec8John McCall
41369c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
41372f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
41382f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
41392f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
41402f514480c448708ec382a684cf5e035d3a827ec8John McCall
41412f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4142ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
4143c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
4144ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
4145ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
4146b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  else if (DD.getUnknownObjCClass()) {
4147b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_fwdclass_message)
4148b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian      << DD.getDeprecationDecl()->getDeclName();
4149b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class);
4150b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  }
4151c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
4152c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
4153ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
415454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
415554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
41565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
41578e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
415889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
415954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4160eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
4161b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
4162b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              UnknownObjCClass,
4163b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              Message));
416454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
416554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
416654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
416754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
41683a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
416954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4170ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
4171c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
4172c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
41738e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
4174743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
41758e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
417689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
41778e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
417889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
417989ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
41808e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
418154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4182