SemaDeclAttr.cpp revision f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9fa
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  ExpectedParameterOrMethod,
39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrBlock,
40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassOrVirtualMethod,
41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrParameter,
42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClass,
43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVirtualMethod,
44883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassMember,
45883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariable,
46883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedMethod,
47db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  ExpectedVariableFunctionOrLabel,
48db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  ExpectedFieldOrGlobalVar
49883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall};
50883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall
51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
52e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
53e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
54e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
5587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D,
56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
5887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
6087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
6287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
66bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
686217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
69755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
706217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
71d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
72183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
78d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
79a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
8087c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) {
8187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return getFunctionType(D, false) != NULL;
82a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
83a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
84a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
85d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
8787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) {
8887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isFunction(D)|| isa<ObjCMethodDecl>(D);
89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
903568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
93620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
9487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
9587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isFunctionOrMethod(D))
96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
9887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
101620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
10287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<BlockDecl>(D);
103620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
104620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
105711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
106711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
10787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) {
108f85e193739c953358c865005855253af4f68a497John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
10987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
11087c44604325578b8de07d768391c1c9432404f5aChandler Carruth         isa<ObjCPropertyDecl>(D);
111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
112711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
113d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
114d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
115620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
11687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) {
11787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
11872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
119620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
12087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
121d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
122d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
1233568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1243568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
125d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
126d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
127d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
12887c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) {
12987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
13072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
13187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
132d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
13387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_size();
1343568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1353568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
13787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
13872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
13987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
140d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
141bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
1433568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1443568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
14587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) {
14687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
14887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->getResultType();
1495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
15187c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) {
15287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D)) {
15372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1543568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
15587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
156db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
157d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
15887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    return cast<ObjCMethodDecl>(D)->isVariadic();
1593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1603568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1613568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
16287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) {
16387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
16507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
16607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
16707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
169183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
170b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
172bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
173506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
174506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
177506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
178bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
184085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1856217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
187085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1896217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
191085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
192bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
194465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
197085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
198085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
199085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
200b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May
201b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth                                  unsigned int Num) {
2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (Attr.getNumArgs() != Num) {
2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    return false;
2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  }
2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  return true;
2101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth}
2111731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
212db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May
214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
215b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
216b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                  unsigned int Num) {
217b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (Attr.getNumArgs() < Num) {
218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return false;
220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  return true;
223db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
224db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
225db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski///
226fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var
227fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable
228fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
22939997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) {
230fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (isa<FieldDecl>(D))
231fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return true;
23239997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const VarDecl *vd = dyn_cast<VarDecl>(D))
233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
235fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
236fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
237fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
238b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool.
239b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) {
240b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = Exp->getType();
241b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return QT->isBooleanType() || QT->isIntegerType();
242b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
243b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
244fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
245fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type.
246fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message.
247fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise
248fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
24939997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool checkIsPointer(Sema &S, const Decl *D, const AttributeList &Attr) {
25039997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
251fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
25239997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer    if (QT->isAnyPointerType())
253fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
254fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_pointer_attribute_wrong_type)
255fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
256fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
257fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
258fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
262fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
263b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points
264b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit.
2657d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) {
2667d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const RecordType *RT = QT->getAs<RecordType>())
267b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return RT;
2687d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2697d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  // Now check if we point to record type.
2707d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const PointerType *PT = QT->getAs<PointerType>())
2717d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer    return PT->getPointeeType()->getAs<RecordType>();
2727d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2737d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  return 0;
274b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
275b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
2763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType
2773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// resolves to a lockable object. May flag an error.
278d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramerstatic bool checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
279d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer                                   const RecordType *RT) {
2803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // Flag error if could not get record type for this argument.
281d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT) {
2823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_class)
2833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      << Attr.getName();
2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return false;
2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
286634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  // Don't check for lockable if the class hasn't been defined yet.
287634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  if (RT->isIncompleteType())
288634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins    return true;
2893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // Flag error if the type is not lockable.
290d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT->getDecl()->getAttr<LockableAttr>()) {
2913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_lockable)
2923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      << Attr.getName();
2933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return false;
2943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  return true;
2963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
298b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
299b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// from Sidx, resolve to a lockable object. May flag an error.
3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with.
3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function
3023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list.
3033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskistatic bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
3043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         const AttributeList &Attr,
3053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         SmallVectorImpl<Expr*> &Args,
306b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
307b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
3083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
309b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
3103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
311ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    if (ArgExp->isTypeDependent()) {
312ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      // FIXME -- need to processs this again on template instantiation
313ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      Args.push_back(ArgExp);
314ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      continue;
315ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    }
316b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
318b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
321b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
325b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
326b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
327b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
328b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
3293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
3303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
3313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
332b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
333b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
334b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          return false;
335b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
3363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
3373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        RT = getRecordType(ArgTy);
338b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
339b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
340b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (!checkForLockableRecord(S, D, Attr, RT))
342b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return false;
343b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
345b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
346b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return true;
347b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
348b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
349e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
350e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
351e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
352e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
3533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
3543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
3553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
3563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
357fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
358fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
359fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
360fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
361fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
362fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
363fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
364fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
365fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
366fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
367b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
368fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
369fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
370fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
371fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
372fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
373fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
374fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
375768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
376fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
377768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
378fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
379fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
380db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
381b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
382db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
383db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
384b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
385db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
3873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
3883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
389db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
392b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
393db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
394db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
395db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
396db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
397db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
398db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
3997b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  if (!Arg->isTypeDependent()) {
4007b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType())))
4017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins      return;
4027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    // FIXME -- semantic checks for dependent attributes
4037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
404b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
405db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
406768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
4073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 S.Context, Arg));
408db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
409768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
410db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
411db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
412db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
413fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
414fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
415fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
416fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
418fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
419fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4201748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
421fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
422fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
423fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
424fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
425fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
427fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
428768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
430768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
440b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
444fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
446768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
449fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
45071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D,
45171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany                                     const AttributeList &Attr) {
45271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  assert(!Attr.isInvalid());
45371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
45471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!checkAttributeNumArgs(S, Attr, 0))
45571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
45671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
45771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
45871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
45971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany      << Attr.getName() << ExpectedFunctionOrMethod;
46071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
46171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  }
46271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
46371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
46471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany                                                          S.Context));
46571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany}
46671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
467db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
468db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
469db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
470db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
471b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
472db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
473db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
474db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
475b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
476b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
477db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
478b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
479db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
480db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
482b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // Check that this attribute only applies to lockable types
483b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
484b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
485b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
486b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
487b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      S.Diag(Attr.getLoc(), diag::err_attribute_decl_not_lockable)
488b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
489b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
490b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
491b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
492b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
494b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
4953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
496b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
497b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
4993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
502db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
503768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
5043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                    StartArg, Size));
505db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
506768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
5073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                   StartArg, Size));
508db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
509db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
510db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
511b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
512db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
514db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
515db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
516b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
517b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
518db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
519db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
520db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
521db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
522db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
523b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
5253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
526b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
527b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
532db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
533768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
5343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
5353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
537768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
5383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        S.Context, StartArg,
5393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        Size));
540db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
541db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
542db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
543b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
544db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
545db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
546b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
547db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
549b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
550b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
551db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
554db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
555db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
556b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
557b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
558b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
559b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
560b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
561b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 2> Args;
563b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1))
565b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
566b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
571768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
5723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              S.Context,
57369f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                              Attr.getArg(0),
5743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              StartArg, Size));
575db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
576768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
57769f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           S.Context,
57869f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           Attr.getArg(0),
57969f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           StartArg, Size));
580db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
583b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
586b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
587db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
589b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
591db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
592db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
593db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
594db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
595b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
5973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
598b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
599b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
604db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
605768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
6063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            S.Context, StartArg,
6073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            Size));
608db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
609768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
6103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         S.Context, StartArg,
6113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         Size));
612db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
613db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
614db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
615b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
616db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
617db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
620b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
621db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
622db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
623db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
624db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
625db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
626b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
6283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
629b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
630b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
635768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
6363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
637db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
638db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
639db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
640b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
641db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
643b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
6453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
646db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
647b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
648db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
650db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
651db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
652db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
654b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
655b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
6573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType())))
6583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return;
6593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
660768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg));
661db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
662db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
663db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
664b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
666db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
667b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
668db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
670b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
671db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
672db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
673db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
674db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
675db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
676b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
6783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
679b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
680b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
685768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
6863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
687db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
688db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
689db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
6911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
69287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
693545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
694803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
695545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
6966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
697bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
6999cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7009cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
7019cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
7039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
704f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
705e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    SourceLocation TemplateKWLoc;
706f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
707f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
7084ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
709e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id,
710e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                          false, false);
7114ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
7124ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
7134ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
7144ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
7159cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
7169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
7171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
7189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
7191731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
7207a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
7216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7229cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7239cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
7249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
7259ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
7269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
727ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
728a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
729bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7309cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
7319cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
7326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
7371731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
7386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
739bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
74087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
741768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
74287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
7436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
7446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
7456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
746803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
747fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
74808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
7496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
750768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
7516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
7523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
7536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
75687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
757768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
758c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
759c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
760c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
761c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
7621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
76396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
7641731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
76596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
766bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
76763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
76887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
76963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
770768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
77163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
77263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
77363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7744ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
77563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
77663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7772f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
7782f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // The IBOutlet/IBOutletCollection attributes only apply to instance
7792f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // variables or properties of Objective-C classes.  The outlet must also
7802f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // have an object reference type.
7812f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
7822f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
7830bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
7842f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << VD->getType() << 0;
7852f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
7862f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
7872f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7882f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
7892f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
7900bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
7912f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << PD->getType() << 1;
7922f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
7932f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
7942f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7952f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else {
7962f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
7972f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    return false;
7982f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7992f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8002f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  return true;
8012f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek}
8022f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
80463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
8051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
80663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
8072f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8082f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
80963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
81063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8112f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
81296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
81396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
8141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
8151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
816857e918a8a40deb128840308a318bf623d68295fTed Kremenek
817857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
818a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
819857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
820857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
821857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
822857e918a8a40deb128840308a318bf623d68295fTed Kremenek
8232f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
824857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
8252f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
826a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
827a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
828f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian    II = &S.Context.Idents.get("NSObject");
8293a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
830b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
83187c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
832a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
833a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
834a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
835a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
836b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
837a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
838a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
839a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
840a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
841f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
842a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
843a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
844a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
845f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
846f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
847857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
848857e918a8a40deb128840308a318bf623d68295fTed Kremenek
849d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
85068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
85168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
85268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
85368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
85468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
85568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
85668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
85768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
85868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
85968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
86068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
86168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
86268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
86368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
8641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
865bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
866bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
86787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
868fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
869883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
870eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
871eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
872bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
87307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
87407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
87587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
87687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
877eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
878eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
8795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
880bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
881eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
882eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
883bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
884bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
885eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
8867a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
887eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
888ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
889ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
890fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
891fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
892eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
893eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
894bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
895eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
896bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
897eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
898fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
89930bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
900eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
901eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
902bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
903465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
90407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
90507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
90607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
90707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
90807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
90907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
91007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
91107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
91207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
913eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
914eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
91587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
916d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
91768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
918dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
919eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
920c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
921fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
9227fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
923eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
924bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
925eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
926eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
928bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
929bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
9307fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
93187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
93287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
933d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
934dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
935d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
93646bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
937bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
938ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
93960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
94060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
94160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
94260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
94360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
9447fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
94560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
946eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
9477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
9487fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
9497fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
950dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
951768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
952cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
953eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
954eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
9551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
956dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
959dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
960dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
961dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
9622a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
9632a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
964dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
965dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
966dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
967dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
968dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
969dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
970dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
971cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
9722a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
9732a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
974cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
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_holds:
981cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
982dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
983dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9862a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9872a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
988cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
989dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
990dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
991dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
992dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
993dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9942a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9952a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
9962a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
9972a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
998dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
999dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
100087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
1001883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1002883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1004dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
100607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
100707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
100887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
100987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1010dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10115f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
1012dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1013dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
1014dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
1015dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
1016dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10175f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10192a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
10202a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1021dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10227a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1023dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1024dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1025dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1026dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1027dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1030dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1031dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1032dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1033dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1034dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1035dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1036dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1037dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
103907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
104007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
104107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
104207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
104307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
104407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
104507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
104607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
104707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1048dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1049cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1050cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
105287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1053dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1055dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1056cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1057dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1058dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1059dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1060dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1061dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1062dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1063cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1064dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1065dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
10667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1067dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1068dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1069dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1070dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1072dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1073dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1074dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1075dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1077dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1078dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1079dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1080dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1081cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
108287c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
108387c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1084cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1085cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1086cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1087cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1089cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1090cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1091dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1092dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1093dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1094dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1095dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1096dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1097dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1098dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1099dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1100dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1101cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1102cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1103cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1104cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1105dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1106cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
110787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1108cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1109dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1110dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1111332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1112332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1113332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1114332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1115332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1116332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1117332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1118332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1119332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1120332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1121332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1122332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1123332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1124332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1125332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1126332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1127332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
112811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
112911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
113111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
113211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
113311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
113411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
113511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
113611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
113787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1138332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1139883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1140332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1141332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1142332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
114387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1144332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
114511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
114611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
114711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
114811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
114911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
115011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
115211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
115587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
11567a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
11577a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1158332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
11597a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
116011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
116111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
116211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
116411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
116611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
117111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
117311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
117411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
117711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
117811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1180332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1181332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
118211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
118311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
118411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
118511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
118611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
118711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
118811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
118911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
11907a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
119111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
119211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
119311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11945cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
119511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
119611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
119711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
119811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
119911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
120011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1201768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1202f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
120311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
120411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1205768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
120611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
120711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
12081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
12096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1210545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
12113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1214bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12157a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
12166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
12176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1218bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12195cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1220fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
12226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1224bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1225bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1226f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1227f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1228f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1229f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
12306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1231bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1232768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1233f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
12346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1237dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
12381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1239dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1240dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
124187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1242dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1243883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1244dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1245dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1246dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1247768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1248dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1249dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
12501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
12511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1252dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1253831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
12543c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1255af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1256af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
12575bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
125887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
12595bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1260883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
12615bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
12625bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1263bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1264768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1265af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1266af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
12671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1268dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1269831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
127076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
127176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
127276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
12731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
127487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
12762cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1277768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
12782cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
12792cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1280fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1281fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
12822cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
128376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
128476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
12851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
128634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
12871731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
128834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
128934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1290768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
129134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
129234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
12931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
129456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
129587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1296768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1297722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1298722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1299883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1300a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1301a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
13021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
130356aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
130487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1305768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1306722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1307722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1308883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1309a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1310a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
13111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
131287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1313711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1314711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1315711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
131687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1317711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1318883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1319711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1320711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1321711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1322768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1323711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1324711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1325711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1326831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1327711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1328711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1329711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1330711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1331711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1332711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1333b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1334b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
13361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1337b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1338b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1339b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1340b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13411731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
13421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1343b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
134487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
134587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
13463ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
13473ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1348e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1349e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1350b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1351883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1352b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
135319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
13546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1355b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1356768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
13576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
135935cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
13601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
136135cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
136235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
136335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1364f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1365f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1366f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1367f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1368f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
136935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
137135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
137335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
137435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
137535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
137635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
137835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
137935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
138035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
138135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
138235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
138335cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
138487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
138535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1386883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
138735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
138835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
138935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
139087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
139135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
139235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
139335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
139435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
139587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
139601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
139701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
139801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
139901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
140001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
140101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
140201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
140301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
140401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
140501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
140601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
140701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1408f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1409f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
141001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
141101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
141201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
141301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
141401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
141501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
141601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1417768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
141835cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
141935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
14201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
142187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1422bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1423883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1424bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1425bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1426bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1427bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1428bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
14291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
143073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1431831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
143373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
143473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1435bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
143687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
143787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1438fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1439883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
144073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
144173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1442bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1443768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
144473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
144573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1446f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1447f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1448f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1449f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1450f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1451f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1452f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1453f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1454f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1455f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1456f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1457f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1458f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1459f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1460f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1461f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1462f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
14631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1464b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1465831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1466b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1467b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1468b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1469bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
147087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1471186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1472b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1473b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1474b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
147587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1476b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1477883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1478b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1479b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1480bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1481768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1482b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1483b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
14841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1486bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1487bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14937a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1495ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1496ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1497fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
14993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1503bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
150487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1505fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1506883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1510768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1511f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
15123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1516bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1517bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
15183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1519bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
15223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
15237a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
15243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1525ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1526ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1527fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
15293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1533bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
153487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1535fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1536883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1540768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1541f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
15423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1545951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1546951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1547bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1548c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1549c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1550951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1551c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
15525f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1553951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1554951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1555c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1556951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1557951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1558c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1559c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1560951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
15616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1562bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1563768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str));
15646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1567951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1568951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1569bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1570bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1571bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1572951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1573c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
15745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1575951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1576951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1577c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1578951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1579c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1580c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1581c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1582951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1583c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1584768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str));
1585bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1586bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1587742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1588742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1589742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1590742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1591742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1592742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1593742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1594742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1595742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1596768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1597742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1598742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
159971207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
1600e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                            const AttributeList &Attr) {
1601341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  if (!isa<ObjCInterfaceDecl>(D)) {
1602341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
1603341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    return;
1604341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  }
1605341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian
1606e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1607e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  if (NumArgs > 0) {
1608e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1609e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    return;
1610e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  }
1611e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
161271207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
1613e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                 Attr.getRange(), S.Context));
1614e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian}
1615e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
16161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
16171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
16180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
16190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
16200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16215f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
16220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
16230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
16240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
16250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
16260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
16280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
16310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
16320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1633b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
16340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1635c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
16360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
16370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
16383b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Deprecated.Version)) {
16390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
16410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
16463b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Obsoleted.Version)) {
16470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16510a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16520a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16530a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
16543b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Deprecated.Version <= Obsoleted.Version)) {
16550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
16560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16570a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
16580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1661006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  StringRef Str;
1662006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  const StringLiteral *SE =
1663006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
1664006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  if (SE)
1665006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    Str = SE->getString();
1666006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian
1667768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context,
16680a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
16690a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
16700a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1671b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1672006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                IsUnavailable,
1673006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                Str));
16740a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
16750a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
16781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
16796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1680bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
16826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
16836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1684bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16855cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1686fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
16873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
16886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1690bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1692cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1693bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1694c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1695cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1696c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1697cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1698c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1699cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
17004188760f6bb20f91c6883dffd89204419f852deeJohn McCall  else if (TypeStr == "protected") {
17014188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // Complain about attempts to use protected visibility on targets
17024188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // (like Darwin) that don't support it.
17034188760f6bb20f91c6883dffd89204419f852deeJohn McCall    if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
17044188760f6bb20f91c6883dffd89204419f852deeJohn McCall      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
17054188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Default;
17064188760f6bb20f91c6883dffd89204419f852deeJohn McCall    } else {
17074188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Protected;
17084188760f6bb20f91c6883dffd89204419f852deeJohn McCall    }
17094188760f6bb20f91c6883dffd89204419f852deeJohn McCall  } else {
171008631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
17116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1713bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1714768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type));
17156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
17181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1719d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1720d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
172187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1722883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1723d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1724d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1725d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
172687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
172787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
172887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1729d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1730d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
173187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1732d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
173387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1734d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1735d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1736d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17375f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1738d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1739d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1740d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1741d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1742d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1743d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1744d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1745d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1746d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1747d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1748d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1749d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1750d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1751d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1752d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1753d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
175487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1755d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1756d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1757d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1758f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1759f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1760f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1761f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1762f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1763f85e193739c953358c865005855253af4f68a497John McCall    return;
1764f85e193739c953358c865005855253af4f68a497John McCall  }
1765f85e193739c953358c865005855253af4f68a497John McCall
1766768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
1767f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1768d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1769d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
17711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
17721731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
17730db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1774bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17750db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
17760db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
17770db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
17780db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
17790db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1780bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1781768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
17820db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
17830db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
17841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1785fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
17862b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1787fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1788fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1789162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1790fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1791fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
17926217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1793fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1794fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1795fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1796fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1797f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  else if (!isa<ObjCPropertyDecl>(D)) {
1798f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // It is okay to include this attribute on properties, e.g.:
1799f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1800f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
1801f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1802f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // In this case it follows tradition and suppresses an error in the above
1803f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // case.
18049b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
1805f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  }
1806768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
1807fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1808fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1809bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
18101b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1811f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
18122b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1813f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1814f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1815f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1816f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1817f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1818f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1819f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1820f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1821768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
1822f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1823f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
18241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1825bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1826fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
18273c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
18289eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18299eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1830bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18319eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
18323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
18339eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18349eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1835bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1836cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
183792e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
18389eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
18399eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1840fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
18413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
18429eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18439eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1844bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1845768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
18469eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
18479eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
18481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1849770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1850770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1851bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1852770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1853bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1854bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18553323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
1856770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
18577a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1858770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1859ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1860ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1861fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1863770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1864770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1865bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18663323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
1867fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1868fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1869770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1870770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
18713323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
18723323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
1873770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1874770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
18753323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
1876770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
18777a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1878770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1879ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1880ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1881fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1883770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1884770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1885770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1886bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18873323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
1888770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1889770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1890fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1891fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1892770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1893770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1894770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1895770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
189687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
18973323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
1898897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1899897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1900897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1901897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1902bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1903897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
19043bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1905770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1906bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
190787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1908770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
19093bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1910770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
19112f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1912a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
1913a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    if (!BD->isVariadic()) {
1914a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
1915a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      return;
1916a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    }
191787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
19182f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1919daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
192087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1921f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
19222f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
19233bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
19243bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
19252f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
19262f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1927ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
19282f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1929883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
19302f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
19312f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1932770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1933fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1934883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1935770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1936770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1937768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
1938f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1939770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1940770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
19411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1942026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
19431731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1944026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1945026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1946f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1947026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1948883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1949026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1950026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1951bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1952f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1953f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1954f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1955f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1956f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1957f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1958f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1959f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1960f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1961f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1962f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1963f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1964768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
1965026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1966026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
19671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
196987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
197087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19736e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
197487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
197513c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    if (isa<CXXRecordDecl>(D)) {
197613c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
197713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      return;
197813c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    }
197987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
198087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1981f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1982f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1983f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
198487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1985332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1986332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1987332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
198887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
19896e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19906e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1991bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1992768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
19936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19966e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
19971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
19986e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
20006e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20016e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
20026e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
20030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
20040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
20050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
20060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
20070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
2008def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2009bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
201090eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2011def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
2012def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
2013c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2014883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
20156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20166e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20176e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
20186e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
2019768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
20206e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
20216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
20231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
20246f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
20251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
20266f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
20276f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20286f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
20296f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
20307a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
20316f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
2032ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2033ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
20346f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
20356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
20366f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
20376f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
20386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
20396f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
2040768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
2041cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
20426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
20436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
20446f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
204617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
20471731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
204817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
204917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
205017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
205117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
20527a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2053797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
205417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
2055797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
205617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
205717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
20581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2059797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
2060bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2061a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2062a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2063a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2064797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2065797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
20661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2067a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2068a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2069a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2070a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2071a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2072a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
2073768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context,
2074f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
207517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
207617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
20776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2080831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
20813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
20826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2084b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
208587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2086b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2087ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2088b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2089768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2090b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
20916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2094232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2095831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
20963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2097232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2098232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2099bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
210087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2101b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2102ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2103b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2104768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2105b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2106232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2107232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
21081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2109232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
21101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2111232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2112bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2113768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2114232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2115232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
21161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2117bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2118f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2119f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2120f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2121bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2122f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2123f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2124f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2125f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2126bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
212787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2128bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2129f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2130f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2131f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2132f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2133bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2134f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2135c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2136f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2137f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2138f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2139f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2140f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2141f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2142f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2143f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2145f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2146f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2147f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2148f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2149f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2150f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2151f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2152f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2153f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2154f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2155f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2156f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2157f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2158f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2159bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
216089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
216189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
216289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
216389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2164b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2165b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2166f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
216789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
216889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
216989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
217089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2171bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2172768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
21735f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
2174f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2175f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
21781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21791731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
21805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21811731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
218287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
21835b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2184883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
21855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
218707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
218807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
218907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
219087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
219187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
21925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
219307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
21945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
21957a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
21965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2197ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2198ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
21995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
22005b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
22015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
22055b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
22065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
22075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2209bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2211bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
221207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
221307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
221407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
221507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
221607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
221707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
221807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
221907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
222007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
22215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
222287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2223bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
22255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
22265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22286217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2231bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
22325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
223587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
22365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
22375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22396217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2242bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
22435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2245bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2246bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2247768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
224807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
22495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
22505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
22512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
22522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
22532b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
22542b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
22552b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
22563c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
22572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
22582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
22592b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22602b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
22612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
22625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
22632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
22642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
22652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
22662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
22672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
22682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
22692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
22702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
22722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
227369d53845c68a4f01920b58ba6ce507d78220689cJean-Daniel Dupas      Format == "strfmon" || Format == "cmn_err" || Format == "vcmn_err" ||
2274cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2275cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
22762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
22772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2278bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2279bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
22803c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
22813c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
22832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
22842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2285521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2286521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
22871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
22881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
2289521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
2290521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2291521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2292521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2293521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
229487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2295b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2296b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2297b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2298b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
229987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2300b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2301b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2302b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2303b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2304b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2305b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2306b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2307b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2308521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2309521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2310521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2311521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2312521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
23137a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2314b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2315521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2316521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2317521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2318521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2319521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2320521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2321521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2322521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
23239f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2324521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2325521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2326521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2327521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2328521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2329521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2330768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2331f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2332521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2333521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2334bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2335bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
23361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
23376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2338545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2339fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
23403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
23416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2344545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
23453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
23466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
234987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2350fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2351883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
235507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
235607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
235787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
235887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
23596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
23606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
23626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
23642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
23652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
23662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
23672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
23682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
23693c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23703c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
23713c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
23723c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2374fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
237501eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
23766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
23807a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2381803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2382ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2383ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2384fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2390fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
23913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
23966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2397bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23984a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
23994a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
240007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
240107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
240207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
24034a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
24044a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
24054a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
24064a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
24071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
240987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
24106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2412085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2413fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2414fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2415085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2416085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
24172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2418390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2419390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2420803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2421390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2422fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2423fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
24246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2425bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
24266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
24276217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2428390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2429fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2430fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
24316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
24357a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2436803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2437ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2438ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2439fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
24403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
24456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
244687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
24476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
24486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
244987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
24506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24543c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
24553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
24562b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
24576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2458fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2459fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
24606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
24636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2464fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
24653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2469b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2470b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
247187c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
247287c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2473b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2474b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2475b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2476b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2477b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2478b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2479b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2480b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2481ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis        f->setRange(Attr.getRange());
2482b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2483b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2484b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2485b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
2486768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format,
2487cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
24882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
24896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
24921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
24936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
24941731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
24956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
24976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24980c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
24990c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
250087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
25010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
25020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
25030c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
250487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
25050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
25060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2507fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2508883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
25096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25125e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall  if (!RD->isCompleteDefinition()) {
2513bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
25140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
25150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
25170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
251817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
251917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
25200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
25210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
25220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25230c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2524bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
25260c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
252790cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2528bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
252990cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
253090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
25310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2533bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
25350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
25360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
25370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
25380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
25390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
25400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
25410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2542bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
25430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2544bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
25450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
25460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
25470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2548bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
25490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
25500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2551bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2552bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2553bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
25546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2555768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
25566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
25601731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
25616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2564797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2565bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
25676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
25686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2569797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
25706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
257277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
257377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
257477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
257577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
257677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
257777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
257877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
257977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
2580768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
2581f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
25826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2586545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
25873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
25886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2590bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2591bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2592bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2593bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
25946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2595545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2596768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0));
25974ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
25984ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
25994ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2600768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0));
26014ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
26024ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2603768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
26040b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  // FIXME: Handle pack-expansions here.
26050b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  if (DiagnoseUnexpandedParameterPack(E))
26060b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne    return;
26070b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne
26084ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
26094ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2610768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
26116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2613bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2614768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
2615cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
261649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
2617282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  ExprResult ICE =
2618282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith    VerifyIntegerConstantExpression(E, &Alignment,
2619282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith      PDiag(diag::err_attribute_argument_not_int) << "aligned",
2620282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith      /*AllowFold*/ false);
2621282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  if (ICE.isInvalid())
262249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
2623396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
26244ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
26254ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2626396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2627396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2628396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2629282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take()));
2630cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2631cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2632768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
2633cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2634cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2635768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS));
2636cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
26376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2638fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2639d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2640bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2641fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2642bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2643bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2644bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
26451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2646fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2647fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2648fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2649fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
26501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2651fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
26521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2653fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2654fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2655fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
26560b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2657fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2658fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2659210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
26605f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2661fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2662fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2663210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2664210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2665fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2666fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2667fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
266873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2669210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2670fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
267173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
267273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
267373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
267473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
267573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
267673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
267773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
267873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
267973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
268073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
268173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
268273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
268373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
268473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
268573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
268673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2687fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2688fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2689fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2690fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2691210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
2692bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2693210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
2694bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
2695fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2696fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2697210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
2698bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2700fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2701fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2703162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2704fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2705fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2708fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2709768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
2710fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
271273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2713183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
271473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
271573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
27162ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
271773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
271873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
271973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
272073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
272173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
272273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
272373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
272473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
272573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2726390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2727390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2728390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2729390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2730f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2731f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2732fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2733fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2734fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
27353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2736fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2737fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
27383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2739fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2740fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
274173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
274273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
274373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
274473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2745fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27460b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2747fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27480b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2749fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2750fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
275173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
275273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
275373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
275473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2755fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27560b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2757fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27580b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2760fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2761fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27620b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2763fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
27640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2765fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27660b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2767fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27700b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2771fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2772bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2773aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2774aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2775aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2776fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2777bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2778aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2779aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2780aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2781fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
278273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
278373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
278473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2785f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2786f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2787f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2788f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2789f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2790f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2791f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2792f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2793f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
279473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2795fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2796fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
279773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
279873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2799fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2800fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2801fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2802162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2803ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2804a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2805ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2806fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2807fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
28080744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
28091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2810d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
28111731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2812d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2813e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
281487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2815d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2816883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2817d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2818d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2819bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2820768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
2821d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2822d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
28231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
28245bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
28251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28265bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
28271731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2828bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
282987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28305bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2831883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28325bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
28335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2834bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2835768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
28365bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
28375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
28381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
28391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
28407255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
28411731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28427255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28431731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
28447255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
284587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28467255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2847883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28487255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28497255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
28507255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2851768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
2852f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
28537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
28547255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
28551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2856ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2857ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2858831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2859ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2860ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2861ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2862ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
286387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2864ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2865883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2866ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2867ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2868ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2869768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
2870ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2871ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2872ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2873ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2874ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2876ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2877ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2878ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2879ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2880ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2881ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2882ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
288387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2884ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2885883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2886ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2887ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2888ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2889768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
2890ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2891ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2892ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2893ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2894ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2896ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2897ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2899ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2900ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
290187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2902ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2903883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2904ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2905ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2906ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
290787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
29082c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2909723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
29102c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
29112c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
29122c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
29132c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
29142c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
29152c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
29162c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
29172c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
29182c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
29192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
29202c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
29212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2922768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
2923ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2924ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2925ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2926ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2927ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2929ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2930ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29311731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2932ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29331731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2934ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
293587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2936ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2937883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2938ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2939ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2940ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2941768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
2942ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2943ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2944ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2945ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2946ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2948ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2949ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2951ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2953ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
295487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2955ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2956883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2957ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2958ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2959ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2960768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
2961ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2962ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2963ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2964ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2965ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
296726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
29681731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
296926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2970bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
297187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2972c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
297326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2974883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
297526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
297626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2977bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
29780130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2979cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2980c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2981c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2982bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2983768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
298426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
298526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
29861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
298787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2988711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
298987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2990e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2991711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
299287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
2993711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2994e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
299587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
299687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
299787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2998711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2999711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3000711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
300187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3002e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
3003768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
3004e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3005e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
3006768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
3007e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3008f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
3009768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
301004633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
3011e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
3012768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
3013e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
301452fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3015768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
301652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
3017414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
301887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
3019414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30205cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
302187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3022414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
302387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3024414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3025414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3026414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
30275f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3028414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
3029414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
3030414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
3031414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
3032414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
3033414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
303487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
303587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3036414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3037414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3038414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
3039768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
3040414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3041e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
3042e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
3043e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
3044e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
3045e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
30461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
304756aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
3048768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3049f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
3050f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
3051711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
3052711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
3053711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3054711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3055831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
3056831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
3057831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
3058711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3059711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
3060711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3061ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
306255d3aaf9a537888734762170823daf750ea9036dEli Friedman
3063414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3064414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3065711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
3066711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
3067711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
3068711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
3069711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
3070711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
3071414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
3072414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3073414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30745cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3075414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3076414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3077414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3078414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3079414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3080414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
30815f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3082414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3083414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3084414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3085414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3086414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3087414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3088414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3089414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3090414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
30917530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("unexpected attribute kind");
3092711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3093711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3094711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3095711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3096711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
30971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
309887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3099711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3100711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
310187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3102711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
310487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
310587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
310687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3107ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3108ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
310955d3aaf9a537888734762170823daf750ea9036dEli Friedman
3110768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3112711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3113711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3114711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
311587c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
311687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3117711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3118711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
311987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
312087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
312187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3122711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3123711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3124711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
312587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
312655d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3127ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3128711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
312987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
313055d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
313187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3132711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
313355d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
313455d3aaf9a537888734762170823daf750ea9036dEli Friedman
3135bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
313687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
313755d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
313887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3139711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
314055d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
314155d3aaf9a537888734762170823daf750ea9036dEli Friedman
3142711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3143bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
314487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3145bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
314687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3147711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
314855d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
314955d3aaf9a537888734762170823daf750ea9036dEli Friedman
3150711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3151ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3152ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
31531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
31547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
31557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
31567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3157bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3158bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
31597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
316287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
31637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3164883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
31657b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31667b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31677b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
31697b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
31707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
31717b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
31727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
31737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
31757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31767b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31777b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
31797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
31807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
31817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
31827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
31837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
31847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
31867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
31877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
31887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3190768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
31917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
31927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
31937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
31947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
31957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
31967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
31977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3199b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3200b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3201b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3202c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
32036c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
32046c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isObjCObjectPointerType() ||
32056c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         S.Context.isObjCNSObjectType(type);
3206c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3207c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
32086c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
32096c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isPointerType() ||
32106c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         isValidSubjectOfNSAttribute(S, type);
3211c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3212c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
321487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3215c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
321687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3217768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3218c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3219c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3220c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3221c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
322287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3223c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3224c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3225c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3226c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3227c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3228c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3229c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3230c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
323187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3232768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3233c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3234c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3235c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3236c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3237768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3238c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3239768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3240c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3241c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
32431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
324487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
324587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3246768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3247c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3248c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3249c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3250768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3251c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3252c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
32541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3255b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3256c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3257bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
325887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3259c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
326087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3261831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
326287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
326387c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3264f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
326587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3266c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
32675dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
326887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3269768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3270883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3271b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3272b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3273bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3274c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3275c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
327687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
32777530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("invalid ownership attribute");
3278c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3279c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3280c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3281c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3282c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3283c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3284c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3285c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3286c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3287c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3288c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3289c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3290c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3291c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3292c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
329387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3294768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3295bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
32965dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3297bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
329887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3299b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3300b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
3301c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
3302768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3303c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3304c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
330531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
3306768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3307f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
330831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
330931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
3310768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3311f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
331231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3313b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
3314768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3315f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3316b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3317b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
3318768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3319f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3320b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3321b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3322b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3323b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3324dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3325dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3326dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3327dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3328dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3329dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3330dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!isa<ObjCMethodDecl>(method)) {
3331dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type)
3332dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc, loc) << attr.getName() << 13 /* methods */;
3333dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3334dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3335dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3336dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3337dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3338f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian
3339f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3340f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3341dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3342dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3343dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3344dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3345dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3346dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3347dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3348dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3349dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3350768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3351dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3352dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
33538dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
33548dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
33558dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
33568dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
33578dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << A.getName() << 0 /*function*/;
33588dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33598dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33608dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33618dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer);
33628dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33638dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
33648dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
33658dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33668dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
33678dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33688dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
33698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33708dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
33718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
33728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
33738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
33748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
33758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33768dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
33798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
33818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
33828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
33848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
33858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
33878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3388fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
3389fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
3390fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
3391fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
3392fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3393fe98da0fa352462c02db037360788748f95466f7John McCall      << Attr.getRange() << Attr.getName() << 14 /*struct */;
3394fe98da0fa352462c02db037360788748f95466f7John McCall  }
3395fe98da0fa352462c02db037360788748f95466f7John McCall
3396fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
3397fe98da0fa352462c02db037360788748f95466f7John McCall
3398fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
3399fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
3400fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
3401fe98da0fa352462c02db037360788748f95466f7John McCall  if (ParmName && S.getLangOptions().ObjC1) {
3402fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
3403fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
3404fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
3405fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
3406fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
3407fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
3408fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
3409fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
3410fe98da0fa352462c02db037360788748f95466f7John McCall      }
3411fe98da0fa352462c02db037360788748f95466f7John McCall    }
3412fe98da0fa352462c02db037360788748f95466f7John McCall  }
3413fe98da0fa352462c02db037360788748f95466f7John McCall
3414fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
3415fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
3416fe98da0fa352462c02db037360788748f95466f7John McCall}
3417fe98da0fa352462c02db037360788748f95466f7John McCall
34181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
34191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
342087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3421f85e193739c953358c865005855253af4f68a497John McCall
342287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3423768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    << Attr.getRange() << Attr.getName() << 12 /* variable */;
3424f85e193739c953358c865005855253af4f68a497John McCall}
3425f85e193739c953358c865005855253af4f68a497John McCall
34261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
34271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
342887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
342987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3430768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << 12 /* variable */;
3431f85e193739c953358c865005855253af4f68a497John McCall    return;
3432f85e193739c953358c865005855253af4f68a497John McCall  }
3433f85e193739c953358c865005855253af4f68a497John McCall
343487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3435f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3436f85e193739c953358c865005855253af4f68a497John McCall
3437f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3438f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
343987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3440f85e193739c953358c865005855253af4f68a497John McCall      << type;
3441f85e193739c953358c865005855253af4f68a497John McCall    return;
3442f85e193739c953358c865005855253af4f68a497John McCall  }
3443f85e193739c953358c865005855253af4f68a497John McCall
3444f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3445f85e193739c953358c865005855253af4f68a497John McCall
3446f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3447f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3448f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3449f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3450f85e193739c953358c865005855253af4f68a497John McCall
3451f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3452f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3453f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3454f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3455f85e193739c953358c865005855253af4f68a497John McCall    break;
3456f85e193739c953358c865005855253af4f68a497John McCall
3457f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3458f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3459f85e193739c953358c865005855253af4f68a497John McCall    break;
3460f85e193739c953358c865005855253af4f68a497John McCall
3461f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3462f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
346387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3464f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3465f85e193739c953358c865005855253af4f68a497John McCall    break;
3466f85e193739c953358c865005855253af4f68a497John McCall  }
3467f85e193739c953358c865005855253af4f68a497John McCall
346887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3469768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3470f85e193739c953358c865005855253af4f68a497John McCall}
3471f85e193739c953358c865005855253af4f68a497John McCall
3472f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
34739428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  switch (Attr.getKind()) {
34749428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  default:
34759428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return false;
34769428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllimport:
34779428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllexport:
34789428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_uuid:
34799428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_deprecated:
34809428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noreturn:
34819428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_nothrow:
34829428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_naked:
34839428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noinline:
34849428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return true;
34859428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  }
348611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
348711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
348811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
348911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
349011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
349111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
34921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
349362ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
349411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
34951731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
349611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
34971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
349811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
349911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
35005cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3501d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3502d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3503d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3504d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3505d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
35065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3507d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3508d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3509d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3510d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3511d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3512d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3513d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3514d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3515d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3516d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3517d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3518d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3519d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3520d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3521d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3522d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
35235f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3524f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3525f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3526f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3527f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3528d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3529d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3530d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3531d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3532d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3533d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3534d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3535d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3536d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3537d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3538d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
353911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
3540768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
354111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3542d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
354311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3544f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3545f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3546b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
35470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
35480744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
35490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
35501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
355260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
35531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
35541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
35551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
355660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
355760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
355860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
355960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3560e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
35611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3563803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
35641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break;
35651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
3566857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
35671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3568803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3569207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3570ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
35716e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
35724211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
35734211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3574bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3575bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3576803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
357760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
357860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
357960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
358060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
358160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
358260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
35831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
35841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3585bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
35861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3587b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
35881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
35891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
35901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3591bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
35921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
35931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
35941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
35951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
35961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
35971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
35983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
35991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
36003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
36011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
36021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
36031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
36041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
36057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
36061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
36077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
36081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
36091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
36101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
36111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
36121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3613dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3614dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3615dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
36161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
36171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
36181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
36191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
36201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
36211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3622b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3623b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
36241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3625f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
36261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3627f85e193739c953358c865005855253af4f68a497John McCall
3628dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3629dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3630dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3631fe98da0fa352462c02db037360788748f95466f7John McCall  case AttributeList::AT_ns_bridged:
3632fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
3633fe98da0fa352462c02db037360788748f95466f7John McCall
36348dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_audited_transfer:
36358dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_unknown_transfer:
36368dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
36378dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3638b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3639c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
36401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3641c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
36421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3643c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3644c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
364531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
364631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3647b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3648b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
36491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3650b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
36516f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
36521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
36536f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3654521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
36551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3656521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
36571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
36581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break;
36591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
36601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3661742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  case AttributeList::AT_arc_weakref_unavailable:
3662742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3663742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
366471207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  case AttributeList::AT_objc_requires_property_definitions:
366571207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
3666e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    break;
36671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
3668f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  case AttributeList::AT_returns_twice:
3669f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
3670f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
36711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
36721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
36731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3674026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
36751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
36761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
36771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3678803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
36791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3680803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
36810db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
36821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
36830db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3684d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
36851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3686d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
36871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break;
36881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
36891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
36901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
36911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
36921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
36931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
36941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
36951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3696bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
369705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
369805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
36997255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
37001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
37017255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
370204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
370304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
370404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3705f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
370652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3707414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
37081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
370904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3710f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
37111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3712f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
371311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
37141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
371511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3716fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3717fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3718fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3719fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3720fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3721fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3722fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3723fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3724fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3725fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3726fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
372771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  case AttributeList::AT_no_address_safety_analysis:
372871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    handleNoAddressSafetyAttr(S, D, Attr);
372971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    break;
3730fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3731fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3732fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3733fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3734fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3735fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3736db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3737db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3738db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3739db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3740db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3741db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3742db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3743db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3744db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3745db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3746db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3747db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3748db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3749db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3750db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3751db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3752db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3753db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3754db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3755db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3756db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3757db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3758db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3759db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3760db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3761db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3762db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3763db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3764db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3765db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3766db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3767db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3768db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3769db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3770db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3771db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3772db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3773db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3774db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3775fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3776803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
377782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
377882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
377982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
37807d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
37817d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3782803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3783803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3784803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3785803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
378660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
378760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
378860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
378960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
37901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
37911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
379260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
379360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
379460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
379560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
379660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
379760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
379860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
379960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
380060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
38011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
380260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
380360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
38041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
380560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
380660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3807803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3808803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3809f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
381060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
381160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
381211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
38131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
381411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
381511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
381611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
381711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
381811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
381960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
382011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3821dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
382211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3823803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3824803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3825803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
38265f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access
38275f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier.
38285f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
38295f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          const AttributeList *AttrList) {
38305f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
38315f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    if (l->getKind() == AttributeList::AT_annotate) {
38325f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      handleAnnotateAttr(*this, ASDecl, *l);
38335f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    } else {
38345f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
38355f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      return true;
38365f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    }
38375f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  }
38385f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
38395f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  return false;
38405f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen}
38415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
3842e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
3843e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
3844e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
3845e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
3846e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
3847e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
3848e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
3849e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3850e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
3851e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
3852e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3853e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
3854e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
3855e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3856e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
3857e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
3858e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3859e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3860e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
3861e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
3862e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
3863e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
3864e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
3865e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
3866e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
3867e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
3868e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3869e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3870e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3871e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
3872900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
3873900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
38747b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3875e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3876e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3877900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
3878900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
3879900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
3880900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
3881900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
3882900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3883900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
3884900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
3885900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
3886900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
3887900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
3888900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
3889900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
3890900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3891900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
3892c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3893900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3894900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
3895900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
3896900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
3897900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
3898900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
3899900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
3900900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
3901900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
3902900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
3903900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
3904900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
39054278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
3906b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3907e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3908e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3909ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3910a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
391116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
391216573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3913b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3914b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3915c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3916b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3917e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3918e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3919e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3920e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3921e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3922e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
39237b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3924c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3925c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3926c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3927c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3928900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
3929cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3930cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3931cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3932c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3933c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3934c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3935c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3936c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3937c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3938c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3939c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3940cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3941e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3942e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3943e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
39440744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
39450744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
39460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
394760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
394860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3949d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3950d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
395131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
395231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
395331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
395431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
395531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
395631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
395731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
395831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
395931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
396031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
396131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
396231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3963d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3964e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3965e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3966e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3967e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
39680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
39697f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
397060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3971bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
39720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
39730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
39740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
39750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
39760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
39770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
397860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3979bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
39800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
39810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
398260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
39830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
398454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3985f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3986f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3987f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3988f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3989f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3990a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
3991a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
3992a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
3993f85e193739c953358c865005855253af4f68a497John McCall    return false;
3994f85e193739c953358c865005855253af4f68a497John McCall
3995f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3996f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3997f85e193739c953358c865005855253af4f68a497John McCall}
3998f85e193739c953358c865005855253af4f68a497John McCall
3999f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
4000f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4001f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
4002f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
4003f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
4004f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
4005f85e193739c953358c865005855253af4f68a497John McCall    return;
4006f85e193739c953358c865005855253af4f68a497John McCall  }
4007175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian  if (S.getLangOptions().ObjCAutoRefCount)
4008175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
4009175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // FIXME. we may want to supress diagnostics for all
4010175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // kind of forbidden type messages on unavailable functions.
4011175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
4012175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag.getForbiddenTypeDiagnostic() ==
4013175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
4014175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
4015175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
4016175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
4017175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
4018f85e193739c953358c865005855253af4f68a497John McCall
4019f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4020f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4021f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
4022f85e193739c953358c865005855253af4f68a497John McCall}
4023f85e193739c953358c865005855253af4f68a497John McCall
4024eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
4025eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
4026eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
4027eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
4028eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4029eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
4030eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
4031eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
4032eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
4033eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
4034eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4035eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
4036eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
4037eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4038eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
4039eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
4040eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
4041eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
4042eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4043eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
4044eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
404554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
404654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4047eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
4048eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
4049eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
405054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4051eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
4052eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
4053eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
4054eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
405554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4056eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
4057eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
405854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4059eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
4060eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
4061eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
406258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
40632f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
40642f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
4065e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall  if (decl) {
4066eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
4067eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
40682f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
40692f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
40702f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
40712f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
40722f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
4073eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
4074eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
4075eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
40762f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
40772f514480c448708ec382a684cf5e035d3a827ec8John McCall
4078eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
40792f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
4080e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        // Don't bother giving deprecation diagnostics if the decl is invalid.
4081e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        if (!decl->isInvalidDecl())
4082e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall          S.HandleDelayedDeprecationCheck(diag, decl);
40832f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
40842f514480c448708ec382a684cf5e035d3a827ec8John McCall
40852f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
4086eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
40872f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
4088f85e193739c953358c865005855253af4f68a497John McCall
4089f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
4090f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
4091f85e193739c953358c865005855253af4f68a497John McCall        break;
409254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
409354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
409454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
409554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
409658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
4097eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
409829233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
409958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
4100eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
41012f514480c448708ec382a684cf5e035d3a827ec8John McCall}
41022f514480c448708ec382a684cf5e035d3a827ec8John McCall
41032f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
41042f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
41050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
41062f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
4107c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    // A category implicitly has the availability of the interface.
4108c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4109c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis      return CatD->getClassInterface()->isDeprecated();
41102f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
41112f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
41122f514480c448708ec382a684cf5e035d3a827ec8John McCall}
41132f514480c448708ec382a684cf5e035d3a827ec8John McCall
41149c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
41152f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
41162f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
41172f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
41182f514480c448708ec382a684cf5e035d3a827ec8John McCall
41192f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4120ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
4121c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
4122ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
4123ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
4124c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
4125c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
4126ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
412754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
412854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
41295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
41308e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
413189ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
413254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4133eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
4134eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
413554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
413654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
413754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
413854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
41393a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
414054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4141ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
4142c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
4143c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
41448e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
4145743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
41468e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
414789ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
41488e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
414989ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
415089ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
41518e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
415254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4153