SemaDeclAttr.cpp revision 83cad4544f8a89fb6a611f330d71d027c238375e
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///
24639997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool checkIsPointer(Sema &S, const Decl *D, const AttributeList &Attr) {
24739997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
248fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
24939997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer    if (QT->isAnyPointerType())
250fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
251fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_pointer_attribute_wrong_type)
252fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
253fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
254fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
255fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
256fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
257fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
258fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
260b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points
261b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit.
2627d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) {
2637d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const RecordType *RT = QT->getAs<RecordType>())
264b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return RT;
2657d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2667d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  // Now check if we point to record type.
2677d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const PointerType *PT = QT->getAs<PointerType>())
2687d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer    return PT->getPointeeType()->getAs<RecordType>();
2697d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2707d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  return 0;
271b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
272b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
2733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType
2743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// resolves to a lockable object. May flag an error.
27583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchinsstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
27683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins                                   QualType Ty) {
27783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  const RecordType *RT = getRecordType(Ty);
27883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins
27983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  // Warn if could not get record type for this argument.
280d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT) {
28183cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_attribute_argument_not_class)
28283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      << Attr.getName() << Ty.getAsString();
28383cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
285634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  // Don't check for lockable if the class hasn't been defined yet.
286634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  if (RT->isIncompleteType())
28783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
28883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  // Warn if the type is not lockable.
289d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT->getDecl()->getAttr<LockableAttr>()) {
29083cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_attribute_argument_not_lockable)
29183cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      << Attr.getName() << Ty.getAsString();
29283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
2933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
296b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
297b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// from Sidx, resolve to a lockable object. May flag an error.
2983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with.
2993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function
3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list.
3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskistatic bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
3023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         const AttributeList &Attr,
3033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         SmallVectorImpl<Expr*> &Args,
304b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
305b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
3063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
307b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
3083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
309ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    if (ArgExp->isTypeDependent()) {
310ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      // FIXME -- need to processs this again on template instantiation
311ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      Args.push_back(ArgExp);
312ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      continue;
313ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    }
314b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
316b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
319b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
323b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
324b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
325b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
326b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
3283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
3293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
330b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
331b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
332b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          return false;
333b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
3343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
335b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
336b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
337b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
33883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    checkForLockableRecord(S, D, Attr, ArgTy);
339b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
341b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
342b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return true;
343b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
344b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
345e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
346e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
347e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
348e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
3493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
3503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
3513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
3523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
353fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
354fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
355fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
356fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
357fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
358fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
359fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
360fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
361fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
362fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
363b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
364fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
365fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
366fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
367fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
368fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
369fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
370fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
371768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
372fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
373768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
374fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
375fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
376db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
377b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
378db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
379db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
380b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
381db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
382db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
3833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
3843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
385db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
387db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
388b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
389db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
392db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
393db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
394db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
3957b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  if (!Arg->isTypeDependent()) {
39683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    checkForLockableRecord(S, D, Attr, Arg->getType());
3977b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
398b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
399db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
400768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
4013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 S.Context, Arg));
402db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
403768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
404db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
405db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
406db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
407fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
408fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
409fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
410fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
411fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
412fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
413fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4141748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
415fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
416fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
418fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
419fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
420fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
421fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
422768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
423fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
424768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
425fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
427fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
428fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
434b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
440768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
44471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D,
44571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany                                     const AttributeList &Attr) {
44671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  assert(!Attr.isInvalid());
44771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
44871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!checkAttributeNumArgs(S, Attr, 0))
44971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
45071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
45171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
45271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
45371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany      << Attr.getName() << ExpectedFunctionOrMethod;
45471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
45571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  }
45671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
45771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
45871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany                                                          S.Context));
45971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany}
46071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
462db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
463db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
464db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
465b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
466db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
467db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
468db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
469b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
470b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
471db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
472b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
473db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
474db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
475db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
476b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // Check that this attribute only applies to lockable types
477b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
478b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
479b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
480b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
48183cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_attribute_decl_not_lockable)
482b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
483b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
484b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
485b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
486b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
488b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
4893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
490b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
491b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
4933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
4943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
4953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
496db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
497768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
4983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                    StartArg, Size));
499db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
500768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
5013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                   StartArg, Size));
502db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
503db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
504db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
505b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
506db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
507db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
508db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
509db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
510b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
511b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
512db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
514db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
515db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
516db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
517b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
5193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
520b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
521b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
526db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
527768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
5283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
5293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
530db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
531768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
5323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        S.Context, StartArg,
5333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        Size));
534db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
535db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
537b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
538db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
539db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
540b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
541db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
542db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
543b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
544b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
545db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
546db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
547db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
549db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
550b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
551b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
552b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
553b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
554b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
555b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 2> Args;
557b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1))
559b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
560b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
565768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
5663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              S.Context,
56769f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                              Attr.getArg(0),
5683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              StartArg, Size));
569db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
570768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
57169f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           S.Context,
57269f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           Attr.getArg(0),
57369f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           StartArg, Size));
574db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
575db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
577b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
579db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
580b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
583b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
586db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
587db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
589b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
5913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
592b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
593b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
598db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
599768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
6003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            S.Context, StartArg,
6013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            Size));
602db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
603768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
6043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         S.Context, StartArg,
6053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         Size));
606db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
607db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
608db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
609b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
610db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
611db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
612db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
613db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
614b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
615db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
616db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
617db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
620b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
6223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
623b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
624b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
629768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
6303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
631db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
633db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
634b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
635db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
636db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
637b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
638db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
6393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
640db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
641b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
645db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
646db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
648b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
649b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
65183cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  checkForLockableRecord(S, D, Attr, Arg->getType());
6523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
653768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg));
654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
656db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
657b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
658db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
659db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
660b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
661db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
662db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
663b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
664db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
666db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
667db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
668db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
669b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
6713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
672b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
673b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
678768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
6793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
680db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
681db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
682db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
6841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
68587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
686545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
687803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
688545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
6896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
690bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
6929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
6949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
6969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
697f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
698e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    SourceLocation TemplateKWLoc;
699f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
700f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
7014ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
702e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id,
703e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                          false, false);
7044ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
7054ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
7064ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
7074ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
7089cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
7099cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
7101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
7119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
7121731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
7137a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
7146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7159cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
7179cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
7189ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
7199cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
720ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
721a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
722bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7239cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
7249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
7256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
7301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
7316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
73387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
734768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
73587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
7366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
7376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
7386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
739803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
740fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
74108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
7426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
743768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
7446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
7453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
7466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
74987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
750768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
751c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
752c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
753c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
754c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
7551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
75696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
7571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
75896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
759bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
76063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
76187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
76263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
763768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
76463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
76563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
76663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7674ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
76863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
76963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7702f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
7712f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // The IBOutlet/IBOutletCollection attributes only apply to instance
7722f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // variables or properties of Objective-C classes.  The outlet must also
7732f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // have an object reference type.
7742f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
7752f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
7760bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
7772f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << VD->getType() << 0;
7782f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
7792f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
7802f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7812f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
7822f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
783f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
7842f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << PD->getType() << 1;
7852f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
7862f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
7872f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7882f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else {
7892f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
7902f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    return false;
7912f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
792f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
7932f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  return true;
7942f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek}
7952f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
7961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
79763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
7981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
79963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
8002f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8012f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
80263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
80363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8042f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
80596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
80696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
8071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
8081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
809857e918a8a40deb128840308a318bf623d68295fTed Kremenek
810857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
811a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
812857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
813857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
814857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
815857e918a8a40deb128840308a318bf623d68295fTed Kremenek
8162f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
817857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
8182f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
819a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
820a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
821f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian    II = &S.Context.Idents.get("NSObject");
8223a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
823b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
82487c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
825a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
826a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
827a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
828a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
829b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
830a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
831a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
832a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
833a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
834f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
835a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
836a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
837a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
838f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
839f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
840857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
841857e918a8a40deb128840308a318bf623d68295fTed Kremenek
842d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
84368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
84468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
84568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
84668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
84768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
84868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
84968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
85068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
85168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
85268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
85368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
85468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
85568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
85668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
8571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
858bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
859bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
86087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
861fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
862883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
863eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
864eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
865bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
86607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
86707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
86887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
86987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
870eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
871eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
8725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
873bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
874eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
875eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
876bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
877bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
878eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
8797a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
880eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
881ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
882ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
883fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
884fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
885eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
886eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
887bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
888eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
889bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
890eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
891fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
89230bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
893eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
894eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
895bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
896465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
89707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
89807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
89907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
90007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
90107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
90207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
90307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
90407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
90507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
906eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
907eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
90887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
909d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
91068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
911dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
912eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
913c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
914fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
9157fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
916eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
917bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
918eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
919eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
920bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
921bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
922bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
9237fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
92487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
92587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
926d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
927dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
928d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
92946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
930bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
931ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
93260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
93360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
93460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
93560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
93660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
9377fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
93860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
939eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
9407fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
9417fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
9427fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
943dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
944768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
945cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
946eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
947eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
9481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
949dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
950dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
951dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
952dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
953dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
954dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
9552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
9562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
959dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
960dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
961dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
962dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
963dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
964cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
9652a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
9662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
967cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
968dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
969dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
970dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
971dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9722a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9732a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
974cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
975dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
976dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
977dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
978dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9792a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9802a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
981cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
982dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
983dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
986dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9872a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
9892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
9902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
991dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
992dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
99387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
994883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
995883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
997dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
998dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
99907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
100007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
100187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
100287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
1008dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
1009dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
1011dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10122a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
10132a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1014dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10157a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1016dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1019dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1020dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1021dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1022dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1023dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1024dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1025dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1026dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1027dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1030dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1031dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
103207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
103307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
103407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
103507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
103607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
103707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
103807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
103907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
104007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1041dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1042cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1043cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1044dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
104587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1046dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1047dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1048dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1049cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1052dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1053dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1055dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1056cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1057dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1058dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
10597a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1060dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1061dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1062dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1063dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1064dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1065dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1066dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1067dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1068dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1069dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1070dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1072dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1073dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1074cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
107587c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
107687c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1077cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1078cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1079cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1080cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1081cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1082cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1083cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1084dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1085dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1086dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1087dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1088dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1089dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1090dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1091dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1092dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1093dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1094cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1095cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1096cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1097cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1098dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1099cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
110087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1101cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1102dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1103dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1104332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1105332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1106332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1107332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1108332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1109332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1110332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1111332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1112332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1113332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1114332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1115332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1116332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1117332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1118332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1119332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1120332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
112111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
112211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
112411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
112511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
112611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
112711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
112811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
112911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
113087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1131332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1132883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1133332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1134332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1135332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
113687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1137332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
113811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
113911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
114011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
114111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
114211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
114311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
114411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
114511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
114611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
114711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
114887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
11497a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
11507a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1151332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
11527a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
115711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
115811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
115911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
116011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
116111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
116211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
116411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
116611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
117111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1173332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1174332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
117711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
117811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
118011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
118111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
118211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
11837a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
118411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
118511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
118611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11875cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
118811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
118911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
119011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
119111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
119211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
119311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1194768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1195f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
119611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
119711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1198768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
119911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
120011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
12011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
12026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1203545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
12043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1207bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
12096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
12106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1211bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12125cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1213fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
12156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1217bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1218bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1219f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1220f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1221f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1222f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
12236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1224bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1225768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1226f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
12276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1230dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
12311731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1232dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1233dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
123487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1235dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1236883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1237dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1238dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1239dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1240768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1241dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1242dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
12431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
12441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1245dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1246831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
12473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1248af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1249af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
12505bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
125187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
12525bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1253883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
12545bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
12555bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1256bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1257768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1258af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1259af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
12601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1261dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1262831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
126376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
126476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
126576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
12661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
126787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
12692cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1270768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
12712cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
12722cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1273fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1274fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
12752cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
127676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
127776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
12781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
127934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
12801731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
128134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
128234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1283768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
128434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
128534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
12861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
128756aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
128887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1289768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1290722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1291722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1292883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1293a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1294a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
129656aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
129787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1298768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1299722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1300722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1301883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1302a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1303a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
13041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
130587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1307711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1308711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
130987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1310711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1311883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1312711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1313711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1314711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1315768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1316711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1317711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1318711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1319831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1320711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1321711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1322711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1323711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1324711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1325711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1326b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1327b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
13291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1330b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1331b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1332b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1333b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
13351731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1336b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
133787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
133887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
13393ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
13403ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1341e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1342e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1343b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1344883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1345b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
134619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
13476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1348b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1349768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
13506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
135235cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
13531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
135435cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
135535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
135635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1357f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1358f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1359f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1360f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1361f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
136235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
136335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
136435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
136635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
136735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
136835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
136935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
137135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
137235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
137335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
137435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
137535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
137635cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
137787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
137835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1379883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
138035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
138135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
138235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
138387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
138435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
138535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
138635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
138735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
138887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
138901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
139001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
139101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
139201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
139301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
139401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
139501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
139601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
139701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
139801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
139901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
140001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1401f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1402f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
140301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
140401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
140501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
140601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
140701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
140801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
140901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1410768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
141135cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
141235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
14131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
141487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1415bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1416883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1417bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1418bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1419bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1420bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1421bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
14221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
142373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1424831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
142673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
142773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1428bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
142987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
143087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1431fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1432883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
143373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
143473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1435bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1436768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
143773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
143873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1439f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1440f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1441f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1442f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1443f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1444f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1445f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1446f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1447f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1448f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1449f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1450f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1451f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1452f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1453f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1454f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1455f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
14561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1457b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1458831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1459b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1460b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1461b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1462bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
146387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1464186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1465b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1466b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1467b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
146887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1469b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1470883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1471b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1472b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1473bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1474768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1475b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1476b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
14771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1479bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1480bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1482bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14867a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1488ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1489ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1490fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
14923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
14933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
14943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
14953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1496bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
149787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1498fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1499883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1503768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1504f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
15053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1509bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1510bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
15113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1512bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
15153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
15167a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
15173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1518ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1519ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1520fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
15223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1526bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
152787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1528fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1529883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1533768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1534f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
15353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1538951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1539951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1540bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1541c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1542c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1543951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1544c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
15455f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1546951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1547951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1548c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1549951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1550951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1551c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1552c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1553951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
15546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1555bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1556768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str));
15576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1560951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1561951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1562bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1563bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1564bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1565951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1566c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
15675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1568951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1569951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1570c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1571951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1572c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1573c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1574c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1575951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1576c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1577768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str));
1578bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1579bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1580742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1581742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1582742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1583742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1584742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1585742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1586742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1587742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1588742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1589768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1590742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1591742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1592b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beardstatic void handleObjCRootClassAttr(Sema &S, Decl *D,
1593b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard                                    const AttributeList &Attr) {
1594b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (!isa<ObjCInterfaceDecl>(D)) {
1595b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1596b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1597b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1598b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1599b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  unsigned NumArgs = Attr.getNumArgs();
1600b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (NumArgs > 0) {
1601b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1602b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1603b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1604b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1605b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
1606b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard}
1607b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
160871207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
1609e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                            const AttributeList &Attr) {
1610341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  if (!isa<ObjCInterfaceDecl>(D)) {
1611341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
1612341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    return;
1613341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  }
1614341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian
1615e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1616e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  if (NumArgs > 0) {
1617e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1618e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    return;
1619e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  }
1620e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
162171207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
1622e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                 Attr.getRange(), S.Context));
1623e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian}
1624e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
16251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
16261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
16270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
16280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
16290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
16310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
16320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
16330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
16340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
16350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
16370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
16400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
16410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1642b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
16430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1644c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
16450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
16460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
16473b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Deprecated.Version)) {
16480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
16500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16510a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16520a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16530a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16540a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
16553b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Obsoleted.Version)) {
16560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16570a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16610a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
16633b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Deprecated.Version <= Obsoleted.Version)) {
16640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
16650a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
16670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16680a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16690a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1670006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  StringRef Str;
1671006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  const StringLiteral *SE =
1672006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
1673006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  if (SE)
1674006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    Str = SE->getString();
1675006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian
1676768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context,
16770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
16780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
16790a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1680b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1681006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                IsUnavailable,
1682006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                Str));
16830a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
16840a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
16871731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
16886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1689bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16907a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
16916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
16926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1693bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16945cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1695fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
16963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
16976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1699bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1701cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1702bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1703c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1704cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1705c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1706cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1707c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1708cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
17094188760f6bb20f91c6883dffd89204419f852deeJohn McCall  else if (TypeStr == "protected") {
17104188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // Complain about attempts to use protected visibility on targets
17114188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // (like Darwin) that don't support it.
17124188760f6bb20f91c6883dffd89204419f852deeJohn McCall    if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
17134188760f6bb20f91c6883dffd89204419f852deeJohn McCall      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
17144188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Default;
17154188760f6bb20f91c6883dffd89204419f852deeJohn McCall    } else {
17164188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Protected;
17174188760f6bb20f91c6883dffd89204419f852deeJohn McCall    }
17184188760f6bb20f91c6883dffd89204419f852deeJohn McCall  } else {
171908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
17206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1722bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1723768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type));
17246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
17271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1728d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1729d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
173087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1731883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1732d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1733d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1734d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
173587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
173687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
173787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1738d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1739d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
174087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1741d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
174287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1743d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1744d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1745d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17465f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1747d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1748d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1749d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1750d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1751d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1752d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1753d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1754d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1755d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1756d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1757d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1758d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1759d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1760d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1761d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1762d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
176387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1764d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1765d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1766d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1767f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1768f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1769f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1770f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1771f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1772f85e193739c953358c865005855253af4f68a497John McCall    return;
1773f85e193739c953358c865005855253af4f68a497John McCall  }
1774f85e193739c953358c865005855253af4f68a497John McCall
1775768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
1776f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1777d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1778d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
17801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
17811731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
17820db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1783bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17840db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
17850db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
17860db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
17870db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
17880db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1789bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1790768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
17910db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
17920db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
17931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1794fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
17952b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1796fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1797fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1798162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1799fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1800fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
18016217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1802fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1803fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1804fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1805fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1806f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  else if (!isa<ObjCPropertyDecl>(D)) {
1807f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // It is okay to include this attribute on properties, e.g.:
1808f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1809f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
1810f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1811f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // In this case it follows tradition and suppresses an error in the above
1812f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // case.
18139b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
1814f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  }
1815768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
1816fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1817fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1818bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
18191b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1820f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
18212b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1822f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1823f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1824f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1825f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1826f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1827f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1828f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1829f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1830768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
1831f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1832f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
18331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1834bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1835fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
18363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
18379eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18389eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1839bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18409eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
18413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
18429eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18439eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1844bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1845cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
184692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
18479eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
18489eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1849fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
18503c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
18519eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18529eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1853bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1854768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
18559eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
18569eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
18571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1858770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1859770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1860bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1861770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1862bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18643323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
1865770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
18667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1867770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1868ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1869ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1870fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1872770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1873770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1874bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18753323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
1876fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1877fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1878770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1879770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
18803323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
18813323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
1882770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1883770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
18843323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
1885770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
18867a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1887770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1888ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1889ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1890fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1892770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1893770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1894770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1895bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18963323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
1897770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1898770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1899fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1900fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1901770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1902770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1903770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1904770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
190587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
19063323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
1907897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1908897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1909897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1910897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1911bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1912897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
19133bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1914770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1915bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
191687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1917770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
19183bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1919770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
19202f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1921a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
1922a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    if (!BD->isVariadic()) {
1923a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
1924a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      return;
1925a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    }
192687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
19272f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1928daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
192987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1930f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
19312f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
19323bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
19333bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
19342f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
19352f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1936ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
19372f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1938883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
19392f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
19402f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1941770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1942fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1943883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1944770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1945770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1946768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
1947f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1948770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1949770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
19501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1951026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
19521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1953026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1954026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1955f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1956026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1957883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1958026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1959026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1960bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1961f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1962f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1963f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1964f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1965f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1966f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1967f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1968f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1969f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1970f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1971f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1972f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1973768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
1974026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1975026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
19761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
197887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
197987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19826e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
198387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
198413c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    if (isa<CXXRecordDecl>(D)) {
198513c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
198613c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      return;
198713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    }
198887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
198987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1990f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1991f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1992f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
199387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1994332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1995332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1996332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
199787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
19986e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19996e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
2000bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2001768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
20026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
20061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
20076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
20096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20106e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
20116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
20120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
20130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
20140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
20150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
20160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
2017def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2018bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
201990eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2020def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
2021def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
2022c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2023883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
20246e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20256e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20266e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
20276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
2028768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
20296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
20306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
20321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
20336f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
20341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
20356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
20366f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20376f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
20386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
20397a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
20406f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
2041ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2042ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
20436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
20446f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
20456f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
20466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
20476f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
20486f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
2049768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
2050cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
20516f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
20526f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
20536f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
205517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
20561731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
205717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
205817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
205917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
206017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
20617a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2062797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
206317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
2064797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
206517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
206617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
20671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2068797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
2069bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2070a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2071a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2072a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2073797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2074797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
20751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2076a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2077a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2078a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2079a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2080a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2081a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
2082768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context,
2083f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
208417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
208517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
20866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2089831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
20903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
20916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2093b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
209487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2095b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2096ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2097b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2098768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2099b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
21006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
21016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2103232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2104831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
21053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2106232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2107232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2108bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
210987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2110b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2111ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2112b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2113768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2114b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2115232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2116232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
21171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2118232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
21191731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2120232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2121bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2122768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2123232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2124232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
21251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2126bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2127f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2128f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2129f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2130bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2131f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2132f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2133f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2134f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2135bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
213687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2137bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2138f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2139f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2140f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2141f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2142bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2143f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2144c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2145f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2146f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2147f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2148f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2149f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2150f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2151f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2152f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2154f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2155f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2156f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2157f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2158f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2159f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2160f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2161f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2162f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2163f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2164f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2165f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2166f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2167f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2168bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
216989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
217089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
217189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
217289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2173b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2174b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2175f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
217689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
217789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
217889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
217989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2180bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2181768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
21825f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
2183f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2184f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2185bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2186bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
21871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21881731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
21895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21901731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
219187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
21925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2193883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
21945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
219607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
219707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
219807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
219987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
220087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
22015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
220207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
22035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
22047a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
22055b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2206ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2207ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
22085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
22095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
22105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
22145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
22155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
22165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2218bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2220bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
222107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
222207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
222307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
222407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
222507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
222607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
222707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
222807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
222907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
22305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
223187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2232bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
22345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
22355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22376217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2240bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
22415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2243bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
224487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
22455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
22465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22486217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2251bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
22525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2254bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2255bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2256768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
225707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
22585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
22595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
22602b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
22612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
22622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
22632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
22642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
22653c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
22662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
22672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
22682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
22702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
22715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
22722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
22732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
22742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
22752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
22762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
22772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
22782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
22792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
22812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
228269d53845c68a4f01920b58ba6ce507d78220689cJean-Daniel Dupas      Format == "strfmon" || Format == "cmn_err" || Format == "vcmn_err" ||
2283cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2284cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
22852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
22862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2287bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2288bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
22893c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
22903c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
22922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
22932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2294521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2295521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
22961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
22971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
22984e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!S.getLangOpts().CPlusPlus) {
2299521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2300521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2301521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2302521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
230387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2304b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2305b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2306b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2307b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
230887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2309b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2310b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2311b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2312b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2313b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2314b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2315b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2316b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2317521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2318521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2319521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2320521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2321521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
23227a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2323b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2324521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2325521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2326521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2327521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2328521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2329521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2330521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2331521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
23329f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2333521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2334521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2335521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2336521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2337521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2338521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2339768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2340f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2341521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2342521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2343bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2344bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
23451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
23466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2347545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2348fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
23493c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
23506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2353545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
23543c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
23556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
235887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2359fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2360883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
236407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
236507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
236687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
236787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
23686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
23696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
23716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
23732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
23742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
23752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
23762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
23772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
23783c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23793c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
23803c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
23813c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2383fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
238401eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
23856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
23897a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2390803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2391ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2392ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2393fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2399fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
24003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
24016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
24056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2406bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24074a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
24084a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
240907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
241007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
241107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
24124a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
24134a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
24144a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
24154a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
24161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
241887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
24196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2421085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2422fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2423fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2424085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2425085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
24262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2427390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2428390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2429803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2430390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2431fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2432fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
24336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2434bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
24356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
24366217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2437390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2438fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2439fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
24406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
24447a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2445803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2446ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2447ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2448fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
24493c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
24546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
245587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
24566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
24576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
245887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
24596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24633c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
24643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
24652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
24666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2467fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2468fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
24696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
24726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2473fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
24743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2478b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2479b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
248087c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
248187c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2482b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2483b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2484b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2485b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2486b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2487b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2488b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2489b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2490ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis        f->setRange(Attr.getRange());
2491b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2492b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2493b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2494b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
2495768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format,
2496cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
24972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
24986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
25011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
25026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
25031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
25046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
25080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
250987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
25100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
25110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
25120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
251387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
25140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
25150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2516fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2517883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
25186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25215e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall  if (!RD->isCompleteDefinition()) {
2522bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
25230c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
25240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
25260c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
252717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
252817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
25290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
25300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
25310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2533bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
25350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
253690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2537bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
253890cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
253990cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
25400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2542bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
25440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
25450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
25460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
25470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
25480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
25490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
25500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2551bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
25520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2553bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
25540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
25550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
25560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2557bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
25580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
25590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2560bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2561bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2562bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
25636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2564768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
25656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
25691731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
25706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25711731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25727a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2573797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2574bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
25766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
25776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2578797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
25796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
258177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
258277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
258377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
258477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
258577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
258677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
258777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
258877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
2589768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
2590f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
25916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2595545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
25963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
25976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2599bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2600bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2601bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2602bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
26036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2604545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2605768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0));
26064ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
26074ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
26084ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2609768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0));
26104ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
26114ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2612768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
26130b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  // FIXME: Handle pack-expansions here.
26140b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  if (DiagnoseUnexpandedParameterPack(E))
26150b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne    return;
26160b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne
26174ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
26184ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2619768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
26206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2622bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2623768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
2624cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
262549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
2626282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  ExprResult ICE =
2627282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith    VerifyIntegerConstantExpression(E, &Alignment,
2628282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith      PDiag(diag::err_attribute_argument_not_int) << "aligned",
2629282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith      /*AllowFold*/ false);
2630282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  if (ICE.isInvalid())
263149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
2632396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
26334ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
26344ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2635396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2636396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2637396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2638282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take()));
2639cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2640cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2641768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
2642cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2643cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2644768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS));
2645cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
26466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2647fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2648d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2649bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2650fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2651bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2652bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2653bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
26541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2655fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2656fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2657fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2658fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
26591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2660fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
26611731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2662fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2663fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2664fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
26650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2666fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2667fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2668210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
26695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2670fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2671fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2672210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2673210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2675fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2676fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
267773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2678210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2679fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
268073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
268173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
268273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
268373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
268473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
268573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
268673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
268773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
268873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
268973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
269073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
269173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
269273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
269373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
269473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
269573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2696fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2700210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
2701bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2702210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
2703bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
2704fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2705fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2706210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
2707bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2708fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2710fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2712162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2713fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2714fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2715fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2716fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2717fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2718768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
2719fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2720fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
272173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2722183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
272373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
272473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
27252ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
272673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
272773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
272873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
272973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
273073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
273173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
273273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
273373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
273473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2735390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2736390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2737390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2738390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2739f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2740f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2741fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2743fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
27443c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2745fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
27473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2748fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2749fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
275073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
275173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
275273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
275373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2754fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2756fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2758fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
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.ShortTy;
2766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2770fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2772fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
27730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2776fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2777fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2780fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2781bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2782aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2783aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2784aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2785fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2786bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2787aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2788aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2789aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2790fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
279173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
279273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
279373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2794f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2795f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2796f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2797f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2798f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2799f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2800f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2801f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2802f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
280373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2804fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2805fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
280673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
280773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2808fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2809fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2810fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2811162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2812ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2813a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2814ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2815fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2816fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
28170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
28181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2819d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
28201731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2821d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2822e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
282387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2824d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2825883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2826d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2827d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2828bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2829768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
2830d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2831d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
28321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
28335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
28341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28355bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
28361731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2837bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
283887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2840883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28415bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
28425bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2843bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2844768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
28455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
28465bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
28471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
28481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
28497255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
28501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
28537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
285487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2856883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28587255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
28597255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2860768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
2861f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
28627255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
28637255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
28641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2865ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2866ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2867831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2868ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2869ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2870ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2871ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
287287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2873ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2874883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2875ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2876ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2877ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2878768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
2879ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2880ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2881ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2882ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2883ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2885ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2886ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2887ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2888ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2889ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2890ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2891ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
289287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2893ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2894883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2895ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2896ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2897ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2898768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
2899ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2900ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2901ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2902ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2903ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2905ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2906ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2908ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2909ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
291087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2911ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2912883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2913ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2914ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2915ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
291687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
29172c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2918723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
29192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
29202c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
29212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
29222c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
29232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
29242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
29252c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
29262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
29272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
29282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
29292c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
29302c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2931768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
2932ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2933ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2934ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2935ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2936ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2938ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2939ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2941ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2943ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
294487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2945ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2946883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2947ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2948ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2949ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2950768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
2951ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2952ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2953ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2954ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2955ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2957ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2958ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2960ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29611731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2962ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
296387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2964ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2965883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2966ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2967ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2968ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2969768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
2970ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2971ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2972ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2973ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2974ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
297626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
29771731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
297826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2979bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
298087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2981c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
298226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2983883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
298426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
298526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2986bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
29870130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2988cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2989c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2990c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2991bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2992768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
299326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
299426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
29951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
299687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2997711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
299887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2999e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3000711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
300187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
3002711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3003e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
300487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
300587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
300687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3007711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3008711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3009711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
301087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3011e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
3012768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
3013e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3014e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
3015768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
3016e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3017f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
3018768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
301904633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
3020e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
3021768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
3022e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
302352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3024768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
302552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
3026414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
302787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
3028414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30295cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
303087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3031414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
303287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3033414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3034414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3035414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
30365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3037414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
3038414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
3039414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
3040414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
3041414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
3042414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
304387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
304487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3045414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3046414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3047414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
3048768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
3049414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3050e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
3051e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
3052e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
3053e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
3054e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
30551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
305656aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
3057768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3058f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
3059f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
3060711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
3061711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
3062711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3063711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3064831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
3065831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
3066831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
3067711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3068711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
3069711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3070ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
307155d3aaf9a537888734762170823daf750ea9036dEli Friedman
3072414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3073414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3074711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
3075711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
3076711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
3077711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
3078711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
3079711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
3080414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
3081414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3082414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30835cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3084414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3085414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3086414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3087414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3088414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3089414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
30905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3091414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3092414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3093414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3094414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3095414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3096414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3097414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3098414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3099414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
31007530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("unexpected attribute kind");
3101711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3102711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3104711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3105711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
31061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
310787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3108711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
311087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3112711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
311387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
311487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
311587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3116ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3117ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
311855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3119768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3120711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3121711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3122711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3123711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
312487c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
312587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3126711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3127711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
312887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
312987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
313087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3131711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3132711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3133711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
313487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
313555d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3136ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3137711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
313887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
313955d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
314087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3141711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
314255d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
314355d3aaf9a537888734762170823daf750ea9036dEli Friedman
3144bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
314587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
314655d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
314787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3148711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
314955d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
315055d3aaf9a537888734762170823daf750ea9036dEli Friedman
3151711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3152bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
315387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3154bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
315587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3156711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
315755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
315855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3159711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3160ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3161ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
31621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
31637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
31647b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
31657b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3166bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3167bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
31687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31697b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
317187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
31727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3173883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
31747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31767b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31777b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
31787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
31797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
31807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
31817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
31827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
31847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
31887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
31897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
31907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
31917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
31927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
31937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
31957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
31967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
31977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3199768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
32007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
32017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
32027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
32037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
32047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
32057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
32067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
32070744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3208b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3209b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3210b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3211c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
32126c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
32136c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isObjCObjectPointerType() ||
32146c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         S.Context.isObjCNSObjectType(type);
3215c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3216c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
32176c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
32186c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isPointerType() ||
32196c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         isValidSubjectOfNSAttribute(S, type);
3220c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3221c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
322387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3224c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
322587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3226768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3227c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3228c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3229c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3230c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
323187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3232c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3233c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3234c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3235c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3236c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3237c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3238c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3239c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
324087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3241768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3242c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3243c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3244c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3245c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3246768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3247c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3248768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3249c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3250c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
32521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
325387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
325487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3255768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3256c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3257c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3258c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3259768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3260c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3261c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
32631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3264b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3265c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3266bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
326787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3268c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
326987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3270831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
32714e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
327287c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3273f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
327487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3275c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
32765dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
327787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3278768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3279883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3280b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3281b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3282bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3283c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3284c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
328587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
32867530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("invalid ownership attribute");
3287c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3288c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3289c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3290c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3291c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3292c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3293c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3294c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3295c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3296c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3297c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3298c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3299c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3300c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3301c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
330287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3303768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3304bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
33055dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3306bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
330787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3308b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3309b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
3310c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
3311768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3312c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3313c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
331431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
3315768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3316f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
331731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
331831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
3319768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3320f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
332131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3322b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
3323768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3324f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3325b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3326b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
3327768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3328f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3329b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3330b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3331b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3332b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3333dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3334dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3335dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3336dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3337dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3338dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3339dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!isa<ObjCMethodDecl>(method)) {
3340dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type)
3341f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
3342dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3343dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3344dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3345dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3346dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3347f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian
3348f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3349f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3350dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3351dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3352dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3353dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3354dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3355dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3356dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3357dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3358dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3359768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3360dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3361dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
33628dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
33638dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
33648dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
33658dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3366f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << A.getRange() << A.getName() << ExpectedFunction;
33678dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33688dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33708dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer);
33718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
33738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
33748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
33768dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
33788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
33808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
33818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
33828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
33838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
33848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
33888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
33908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
33918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
33938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
33948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
33968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3397fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
3398fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
3399fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
3400fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
3401fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3402f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedStruct;
3403fe98da0fa352462c02db037360788748f95466f7John McCall  }
3404fe98da0fa352462c02db037360788748f95466f7John McCall
3405fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
3406fe98da0fa352462c02db037360788748f95466f7John McCall
3407fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
3408fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
3409fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
34104e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (ParmName && S.getLangOpts().ObjC1) {
3411fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
3412fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
3413fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
3414fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
3415fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
3416fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
3417fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
3418fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
3419fe98da0fa352462c02db037360788748f95466f7John McCall      }
3420fe98da0fa352462c02db037360788748f95466f7John McCall    }
3421fe98da0fa352462c02db037360788748f95466f7John McCall  }
3422fe98da0fa352462c02db037360788748f95466f7John McCall
3423fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
3424fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
3425fe98da0fa352462c02db037360788748f95466f7John McCall}
3426fe98da0fa352462c02db037360788748f95466f7John McCall
34271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
34281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
342987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3430f85e193739c953358c865005855253af4f68a497John McCall
343187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3432f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    << Attr.getRange() << Attr.getName() << ExpectedVariable;
3433f85e193739c953358c865005855253af4f68a497John McCall}
3434f85e193739c953358c865005855253af4f68a497John McCall
34351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
34361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
343787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
343887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3439f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedVariable;
3440f85e193739c953358c865005855253af4f68a497John McCall    return;
3441f85e193739c953358c865005855253af4f68a497John McCall  }
3442f85e193739c953358c865005855253af4f68a497John McCall
344387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3444f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3445f85e193739c953358c865005855253af4f68a497John McCall
3446f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3447f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
344887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3449f85e193739c953358c865005855253af4f68a497John McCall      << type;
3450f85e193739c953358c865005855253af4f68a497John McCall    return;
3451f85e193739c953358c865005855253af4f68a497John McCall  }
3452f85e193739c953358c865005855253af4f68a497John McCall
3453f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3454f85e193739c953358c865005855253af4f68a497John McCall
3455f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3456f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3457f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3458f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3459f85e193739c953358c865005855253af4f68a497John McCall
3460f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3461f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3462f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3463f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3464f85e193739c953358c865005855253af4f68a497John McCall    break;
3465f85e193739c953358c865005855253af4f68a497John McCall
3466f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3467f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3468f85e193739c953358c865005855253af4f68a497John McCall    break;
3469f85e193739c953358c865005855253af4f68a497John McCall
3470f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3471f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
347287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3473f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3474f85e193739c953358c865005855253af4f68a497John McCall    break;
3475f85e193739c953358c865005855253af4f68a497John McCall  }
3476f85e193739c953358c865005855253af4f68a497John McCall
347787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3478768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3479f85e193739c953358c865005855253af4f68a497John McCall}
3480f85e193739c953358c865005855253af4f68a497John McCall
3481f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
34829428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  switch (Attr.getKind()) {
34839428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  default:
34849428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return false;
34859428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllimport:
34869428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllexport:
34879428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_uuid:
34889428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_deprecated:
34899428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noreturn:
34909428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_nothrow:
34919428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_naked:
34929428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noinline:
34939428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return true;
34949428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  }
349511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
349611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
349711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
349811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
349911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
350011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
35011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
350262ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
350311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
35041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
350511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
35061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
350711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
350811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
35095cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3510d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3511d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3512d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3513d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3514d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
35155f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3516d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3517d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3518d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3519f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
3520d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3521d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3522d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3523d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3524d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3525d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3526d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3527d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3528d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3529d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3530f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3531d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
35325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3533f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3534f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3535f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3536f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3537d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3538d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3539d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3540d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3541d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3542d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3543d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3544d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3545d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3546d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3547d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
354811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
3549768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
355011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3551d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
355211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3553f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3554f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3555b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
35560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
35570744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
35580744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
35591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
356160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
35621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
35631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
35641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
356560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
356660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
356760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
356860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3569e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
35701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3572803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
3573e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_ibaction:            handleIBAction(S, D, Attr); break;
3574e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutlet:          handleIBOutlet(S, D, Attr); break;
3575e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutletcollection:
35761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3577803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3578207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3579ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
35806e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
35814211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
35824211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3583bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3584bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3585803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
358660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
358760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
358860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
358960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
359060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
359160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
35921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
35931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3594bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
35951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3596b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
35971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
35981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
35991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3600bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
36011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
36021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
36031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
36041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
36051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
36061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
36073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
36081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
36093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
36101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
36111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
36121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
36131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
36147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
36151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
36167b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
36171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
36181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
36191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
36201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
36211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3622dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3623dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3624dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
36251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
36261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
36271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
36281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
36291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
36301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3631b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3632b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
36331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3634f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
36351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3636f85e193739c953358c865005855253af4f68a497John McCall
3637dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3638dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3639dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3640fe98da0fa352462c02db037360788748f95466f7John McCall  case AttributeList::AT_ns_bridged:
3641fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
3642fe98da0fa352462c02db037360788748f95466f7John McCall
36438dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_audited_transfer:
36448dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_unknown_transfer:
36458dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
36468dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3647b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3648c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
36491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3650c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
36511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3652c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3653c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
365431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
365531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3656b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3657b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
36581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3659b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3660e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_reqd_work_group_size:
36611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
36626f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3663521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
36641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3665521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
36661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
3667e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_ms_struct:    handleMsStructAttr    (S, D, Attr); break;
36681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
36691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3670e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_objc_arc_weak_reference_unavailable:
3671742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3672742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
3673b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  case AttributeList::AT_objc_root_class:
3674b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    handleObjCRootClassAttr(S, D, Attr);
3675b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    break;
367671207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  case AttributeList::AT_objc_requires_property_definitions:
367771207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
3678e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    break;
36791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
3680f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  case AttributeList::AT_returns_twice:
3681f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
3682f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
36831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
36841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
36851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3686026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
36871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
36881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
36891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3690803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
36911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3692803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
36930db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
36941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
36950db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3696d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
36971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3698d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
3699e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_NSObject:    handleObjCNSObject    (S, D, Attr); break;
37001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
37011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
37021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
37031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
37041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
37051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
37061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
37071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3708bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
370905f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
371005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
37117255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
37121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
37137255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
371404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
371504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
371604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3717f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
371852fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3719414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
37201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
372104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3722f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
37231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3724f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
372511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
37261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
372711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3728fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3729fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3730fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3731fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3732fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3733fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3734fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3735fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3736fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3737fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3738fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
373971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  case AttributeList::AT_no_address_safety_analysis:
374071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    handleNoAddressSafetyAttr(S, D, Attr);
374171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    break;
3742fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3743fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3744fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3745fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3746fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3747fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3748db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3749db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3750db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3751db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3752db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3753db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3754db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3755db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3756db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3757db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3758db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3759db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3760db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3761db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3762db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3763db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3764db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3765db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3766db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3767db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3768db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3769db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3770db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3771db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3772db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3773db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3774db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3775db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3776db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3777db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3778db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3779db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3780db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3781db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3782db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3783db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3784db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3785db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3786db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3787fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3788803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
378982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
379082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
379182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
37927d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
37937d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3794803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3795803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3796803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3797803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
379860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
379960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
380060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
380160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
38021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
38031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
380460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
380560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
380660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
380760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
380860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
380960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
381060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
381160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
381260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
38131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
381460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
381560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
38161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
381760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
381860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3819803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3820803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3821f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
382260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
382360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
382411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
38251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
382611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
382711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
382811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
382911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
383011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
383160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
383211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3833dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
383411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3835803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3836803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3837803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
38385f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access
38395f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier.
38405f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
38415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          const AttributeList *AttrList) {
38425f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
38435f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    if (l->getKind() == AttributeList::AT_annotate) {
38445f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      handleAnnotateAttr(*this, ASDecl, *l);
38455f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    } else {
38465f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
38475f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      return true;
38485f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    }
38495f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  }
38505f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
38515f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  return false;
38525f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen}
38535f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
3854e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
3855e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
3856e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
3857e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
3858e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
3859e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
3860e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
3861e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3862e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
3863e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
3864e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3865e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
3866e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
3867e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3868e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
3869e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
3870e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3871e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3872e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
3873e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
3874e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
3875e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
3876e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
3877e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
3878e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
3879e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
3880e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3881e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3882e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3883e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
3884900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
3885900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
38867b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3887e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3888e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3889900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
3890900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
3891900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
3892900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
3893900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
3894900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3895900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
3896900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
3897900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
3898900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
3899900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
3900900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
3901900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
3902900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3903900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
3904c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3905900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3906900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
3907900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
3908900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
3909900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
3910900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
3911900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
3912900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
3913900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
3914900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
3915900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
3916900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
39174278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
3918b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3919e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3920e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3921ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3922a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
392316573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
392416573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3925b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3926b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3927c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3928b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3929e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3930e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3931e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3932e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3933e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3934e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
39357b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3936c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3937c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3938c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3939c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3940900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
3941cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3942cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3943cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3944c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3945c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3946c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3947c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3948c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3949c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3950c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3951c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3952cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3953e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3954e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3955e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
39560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
39570744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
39580744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
395960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
396060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3961d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3962d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
396331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
396431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
396531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
396631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
396731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
396831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
396931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
397031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
397131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
397231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
397331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
397431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3975d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3976e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3977e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3978e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3979e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
39800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
39817f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
398260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3983bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
39840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
39850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
39860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
39870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
39880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
39890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
399060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3991bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
39920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
39930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
399460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
39950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
399654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3997f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3998f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3999f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
4000f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
4001f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
4002a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
4003a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
4004a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
4005f85e193739c953358c865005855253af4f68a497John McCall    return false;
4006f85e193739c953358c865005855253af4f68a497John McCall
4007f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
4008f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
4009f85e193739c953358c865005855253af4f68a497John McCall}
4010f85e193739c953358c865005855253af4f68a497John McCall
4011f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
4012f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4013f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
4014f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
4015f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
4016f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
4017f85e193739c953358c865005855253af4f68a497John McCall    return;
4018f85e193739c953358c865005855253af4f68a497John McCall  }
40194e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (S.getLangOpts().ObjCAutoRefCount)
4020175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
4021175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // FIXME. we may want to supress diagnostics for all
4022175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // kind of forbidden type messages on unavailable functions.
4023175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
4024175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag.getForbiddenTypeDiagnostic() ==
4025175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
4026175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
4027175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
4028175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
4029175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
4030f85e193739c953358c865005855253af4f68a497John McCall
4031f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4032f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4033f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
4034f85e193739c953358c865005855253af4f68a497John McCall}
4035f85e193739c953358c865005855253af4f68a497John McCall
4036eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
4037eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
4038eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
4039eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
4040eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4041eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
4042eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
4043eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
4044eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
4045eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
4046eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4047eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
4048eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
4049eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4050eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
4051eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
4052eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
4053eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
4054eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4055eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
4056eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
405754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
405854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4059eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
4060eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
4061eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
406254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4063eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
4064eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
4065eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
4066eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
406754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4068eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
4069eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
407054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4071eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
4072eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
4073eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
407458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
40752f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
40762f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
4077e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall  if (decl) {
4078eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
4079eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
40802f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
40812f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
40822f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
40832f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
40842f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
4085eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
4086eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
4087eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
40882f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
40892f514480c448708ec382a684cf5e035d3a827ec8John McCall
4090eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
40912f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
4092e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        // Don't bother giving deprecation diagnostics if the decl is invalid.
4093e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        if (!decl->isInvalidDecl())
4094e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall          S.HandleDelayedDeprecationCheck(diag, decl);
40952f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
40962f514480c448708ec382a684cf5e035d3a827ec8John McCall
40972f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
4098eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
40992f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
4100f85e193739c953358c865005855253af4f68a497John McCall
4101f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
4102f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
4103f85e193739c953358c865005855253af4f68a497John McCall        break;
410454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
410554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
410654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
410754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
410858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
4109eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
411029233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
411158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
4112eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
41132f514480c448708ec382a684cf5e035d3a827ec8John McCall}
41142f514480c448708ec382a684cf5e035d3a827ec8John McCall
41152f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
41162f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
41170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
41182f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
4119c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    // A category implicitly has the availability of the interface.
4120c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4121c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis      return CatD->getClassInterface()->isDeprecated();
41222f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
41232f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
41242f514480c448708ec382a684cf5e035d3a827ec8John McCall}
41252f514480c448708ec382a684cf5e035d3a827ec8John McCall
41269c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
41272f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
41282f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
41292f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
41302f514480c448708ec382a684cf5e035d3a827ec8John McCall
41312f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4132ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
4133c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
4134ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
4135ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
4136b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  else if (DD.getUnknownObjCClass()) {
4137b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_fwdclass_message)
4138b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian      << DD.getDeprecationDecl()->getDeclName();
4139b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class);
4140b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  }
4141c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
4142c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
4143ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
414454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
414554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
41465f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
41478e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
414889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
414954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4150eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
4151b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
4152b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              UnknownObjCClass,
4153b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              Message));
415454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
415554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
415654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
415754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
41583a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
415954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4160ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
4161c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
4162c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
41638e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
4164743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
41658e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
416689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
41678e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
416889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
416989ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
41708e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
417154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4172