SemaDeclAttr.cpp revision 7530c034c0c71a64c5a9173206d9742ae847af8b
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  }
2863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // Flag error if the type is not lockable.
287d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT->getDecl()->getAttr<LockableAttr>()) {
2883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_lockable)
2893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      << Attr.getName();
2903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return false;
2913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  return true;
2933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
295b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
296b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// from Sidx, resolve to a lockable object. May flag an error.
2973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with.
2983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function
2993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list.
3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskistatic bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         const AttributeList &Attr,
3023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         SmallVectorImpl<Expr*> &Args,
303b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
304b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
3053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
306b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
3073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
308ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    if (ArgExp->isTypeDependent()) {
309ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      // FIXME -- need to processs this again on template instantiation
310ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      Args.push_back(ArgExp);
311ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      continue;
312ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    }
313b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
315b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
318b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
322b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
323b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
324b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
325b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
3283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
329b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
330b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
331b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          return false;
332b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
3333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
3343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        RT = getRecordType(ArgTy);
335b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
336b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
337b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (!checkForLockableRecord(S, D, Attr, RT))
339b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return false;
340b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
342b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
343b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return true;
344b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
345b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
346e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
347e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
348e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
349e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
3503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
3513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
3523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
3533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
354fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
355fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
356fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
357fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
358fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
359fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
360fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
361fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
362fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
363fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
364b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
365fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
366fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
367fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
368fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
369fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
370fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
371fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
372768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
373fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
374768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
375fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
376fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
377db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
378b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
379db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
380db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
381b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
382db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
383db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
3843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
3853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
387db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
388db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
389b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
392db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
393db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
394db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
395db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
3963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
397ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    // FIXME: handle attributes with dependent types
3983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return;
3993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
4003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
4013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType())))
402b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
403b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
404db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
405768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
4063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 S.Context, Arg));
407db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
408768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
409db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
410db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
411db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
412fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
413fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
414fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
415fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
416fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
418fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4191748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
420fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
421fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
422fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
423fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
424fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
425fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
427768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
428fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
429768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
439b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
440fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
444fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
445768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
446fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
449db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
450db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
451db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
452db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
453b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
455db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
456db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
457b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
458b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
459db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
460b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
462db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
463db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
464b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // Check that this attribute only applies to lockable types
465b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
466b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
467b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
468b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
469b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      S.Diag(Attr.getLoc(), diag::err_attribute_decl_not_lockable)
470b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
471b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
472b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
473b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
474b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
476b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
4773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
478b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
479b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
4813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
4823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
4833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
485768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
4863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                    StartArg, Size));
487db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
488768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
4893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                   StartArg, Size));
490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
491db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
492db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
493b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
494db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
495db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
496db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
497db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
498b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
499b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
500db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
501db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
502db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
503db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
504db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
505b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
5073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
508b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
509b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
514db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
515768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
5163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
5173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
518db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
519768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
5203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        S.Context, StartArg,
5213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        Size));
522db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
525b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
526db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
527db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
528b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
529db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
530db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
531b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
532b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
533db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
534db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
535db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
537db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
538b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
539b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
540b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
541b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
542b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
543b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 2> Args;
545b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1))
547b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
548b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
553768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
5543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              S.Context,
55569f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                              Attr.getArg(0),
5563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              StartArg, Size));
557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
558768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
55969f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           S.Context,
56069f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           Attr.getArg(0),
56169f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           StartArg, Size));
562db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
563db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
565b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
566db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
568b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
569db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
571b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
572db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
573db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
574db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
575db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
577b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
5793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
580b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
581b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
5843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
586db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
587768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
5883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            S.Context, StartArg,
5893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            Size));
590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
591768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
5923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         S.Context, StartArg,
5933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         Size));
594db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
595db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
596db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
597b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
598db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
599db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
600db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
601db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
602b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
603db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
604db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
605db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
606db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
607db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
608b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
6103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
611b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
612b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
617768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
6183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
620db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
621db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
622b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
623db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
624db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
625b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
626db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
6273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
628db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
629b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
630db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
631db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
633db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
634db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
636b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
637b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
6393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType())))
6403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    return;
6413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
642768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg));
643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
645db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
646b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
647db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
648db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
649b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
650db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
651db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
652b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
656db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
657db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
658b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
6603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
661b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
662b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  assert(Size == Attr.getNumArgs());
6653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
667768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
6683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
670db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
671db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
6731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
67487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
675545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
676803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
677545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
6786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
679bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
6819cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
6839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
6849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
6859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
686f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
687f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
688f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
6894ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
6904ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
6914ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
6924ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
6934ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
6944ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
6959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
6969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
6971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
6989cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
6991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
7007a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
7016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
7049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
7059ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
7069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
707ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
708a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
709bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7109cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
7119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
7171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
719bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
72087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
721768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
72287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
7236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
7246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
7256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
726803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
727fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
72808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
730768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
7316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
7323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
73687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
737768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
738c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
739c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
740c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
741c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
7421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
74396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
7441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
74596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
746bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
74763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
74887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
74963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
750768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
75163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
75263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
75363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7544ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
75563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
75663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7572f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
7582f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // The IBOutlet/IBOutletCollection attributes only apply to instance
7592f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // variables or properties of Objective-C classes.  The outlet must also
7602f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // have an object reference type.
7612f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
7622f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
7630bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
7642f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << VD->getType() << 0;
7652f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
7662f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
7672f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7682f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
7692f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
7700bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
7712f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << PD->getType() << 1;
7722f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
7732f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
7742f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7752f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else {
7762f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
7772f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    return false;
7782f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
7792f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
7802f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  return true;
7812f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek}
7822f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
7831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
78463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
7851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
78663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
7872f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
7882f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
78963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
79063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7912f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
79296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
79396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
7941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
7951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
796857e918a8a40deb128840308a318bf623d68295fTed Kremenek
797857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
798a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
799857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
800857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
801857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
802857e918a8a40deb128840308a318bf623d68295fTed Kremenek
8032f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
804857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
8052f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
806a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
807a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
808f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian    II = &S.Context.Idents.get("NSObject");
8093a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
810b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
81187c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
812a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
813a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
814a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
815a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
816b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
817a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
818a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
819a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
820a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
821f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
822a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
823a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
824a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
825f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
826f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
827857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
828857e918a8a40deb128840308a318bf623d68295fTed Kremenek
829d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
83068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
83168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
83268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
83368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
83468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
83568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
83668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
83768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
83868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
83968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
84068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
84168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
84268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
84368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
8441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
845bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
846bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
84787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
848fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
849883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
850eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
851eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
852bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
85307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
85407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
85587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
85687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
857eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
858eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
8595f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
860bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
861eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
862eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
864bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
865eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
8667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
867eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
868ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
869ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
870fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
871fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
872eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
873eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
874bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
875eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
876bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
877eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
878fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
87930bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
880eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
881eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
882bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
883465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
88407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
88507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
88607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
88707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
88807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
88907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
89007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
89107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
89207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
893eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
894eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
89587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
896d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
89768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
898dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
899eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
900c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
901fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
9027fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
903eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
904bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
905eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
906eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
907bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
908bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
909bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
9107fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
91187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
91287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
913d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
914dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
915d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
91646bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
917bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
918ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
91960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
92060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
92160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
92260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
92360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
9247fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
92560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
926eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
9277fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
9287fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
9297fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
930dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
931768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
932cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
933eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
934eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
9351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
936dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
937dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
938dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
939dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
940dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
941dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
9422a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
9432a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
944dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
945dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
946dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
947dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
948dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
949dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
950dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
951cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
9522a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
9532a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
954cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
955dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
956dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9592a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9602a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
961cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
962dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
963dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
964dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
965dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9672a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
968cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
969dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
970dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
971dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
972dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
973dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9742a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
9762a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
9772a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
978dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
979dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
98087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
981883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
982883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
983dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
98607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
98707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
98887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
98987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
990dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
992dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
993dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
994dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
995dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
998dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9992a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
10002a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10027a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1004dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1008dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1009dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1010dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1011dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1012dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1013dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1014dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1015dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1016dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
101907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
102007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
102107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
102207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
102307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
102407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
102507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
102607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
102707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1029cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1030cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1031dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
103287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1033dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1034dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1035dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1036cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1037dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1040dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1041dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1042dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1043cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1044dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1045dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
10467a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1047dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1048dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1049dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1052dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1053dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1055dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1056dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1057dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1058dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1059dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1060dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1061cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
106287c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
106387c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1064cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1065cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1066cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1067cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1068cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1069cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1070cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1072dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1073dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1074dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1075dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1077dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1078dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1079dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1080dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1081cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1082cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1083cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1084cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1085dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1086cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
108787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1089dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1090dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1091332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1092332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1093332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1094332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1095332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1096332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1097332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1098332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1099332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1100332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1101332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1102332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1103332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1104332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1105332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1106332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1107332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
110811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
110911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
111111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
111211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
111311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
111411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
111511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
111611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
111787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1118332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1119883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1120332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1121332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1122332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
112387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1124332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
112511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
112611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
112711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
112811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
112911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
113011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
113111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
113211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
113311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
113411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
113587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
11367a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
11377a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1138332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
11397a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
114011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
114111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
114211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
114311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
114411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
114511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
114611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
114711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
114811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
114911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
115011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
115211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
115711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
115811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
115911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1160332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1161332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
116211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
116411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
116611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
11707a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
117111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
117311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11745cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
117711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
117811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
118011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1181768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1182f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
118311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
118411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1185768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
118611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
118711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
11896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1190545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
11913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1194bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11957a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
11966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
11976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1198bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11995cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1200fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
12026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1204bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1205bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1206f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1207f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1208f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1209f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
12106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1211bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1212768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1213f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
12146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1217dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
12181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1219dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1220dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
122187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1222dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1223883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1224dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1225dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1226dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1227768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1228dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1229dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
12301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
12311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1232dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1233831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
12343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1235af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1236af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
12375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
123887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
12395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1240883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
12415bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
12425bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1243bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1244768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1245af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1246af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
12471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1248dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1249831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
125076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
125176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
125276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
12531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
125487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
12562cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1257768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
12582cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
12592cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1260fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1261fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
12622cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
126376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
126476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
12651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
126634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
12671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
126834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
126934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1270768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
127134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
127234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
12731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
127456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
127587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1276768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1277722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1278722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1279883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1280a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1281a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
128356aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
128487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1285768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1286722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1287722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1288883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1289a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1290a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
129287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1293711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1294711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1295711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
129687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1297711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1298883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1299711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1300711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1301711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1302768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1303711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1305711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1306831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1307711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1308711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1309711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1310711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1311711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1312711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1313b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1314b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
13161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1317b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1318b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1319b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1320b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13211731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
13221731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1323b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
132487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
132587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
13263ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
13273ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1328e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1329e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1330b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1331883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1332b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
133319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
13346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1335b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1336768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
13376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
133935cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
13401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
134135cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
134235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
134335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1344f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1345f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1346f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1347f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1348f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
134935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
135035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
135135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
135235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
135335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
135435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
135535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
135635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
135735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
135835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
135935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
136035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
136135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
136235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
136335cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
136487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1366883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
136735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
136835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
136935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
137135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
137235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
137335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
137435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
137601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
137701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
137801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
137901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
138001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
138101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
138201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
138301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
138401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
138501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
138601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
138701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1388f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1389f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
139001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
139101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
139201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
139301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
139401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
139501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
139601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1397768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
139835cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
139935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
14001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
140187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1402bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1403883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1404bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1405bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1406bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1407bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1408bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
14091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
141073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1411831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14123c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
141373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
141473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1415bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
141687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
141787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1418fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1419883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
142073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
142173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1422bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1423768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
142473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
142573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1426f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1427f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1428f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1429f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1430f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1431f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1432f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1433f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1434f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1435f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1436f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1437f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1438f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1439f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1440f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1441f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1442f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
14431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1444b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1445831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1446b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1447b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1448b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1449bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
145087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1451186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1452b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1453b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1454b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
145587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1456b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1457883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1458b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1459b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1460bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1461768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1462b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1463b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
14641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1466bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1467bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1469bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14737a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1475ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1476ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1477fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14783c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
14793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
14803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
14813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
14823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1483bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
148487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1485fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1486883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
14873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
14883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
14893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1490768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1491f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
14923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
14933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1496bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1497bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1499bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
15023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
15037a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
15043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1505ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1506ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1507fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
15093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1513bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
151487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1515fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1516883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1520768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1521f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
15223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1525951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1526951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1527bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1528c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1529c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1530951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1531c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
15325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1533951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1534951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1535c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1536951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1537951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1538c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1539c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1540951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
15416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1542bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1543768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str));
15446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1547951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1548951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1549bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1550bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1551bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1552951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1553c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
15545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1555951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1556951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1557c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1558951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1559c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1560c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1561c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1562951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1563c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1564768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str));
1565bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1566bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1567742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1568742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1569742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1570742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1571742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1572742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1573742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1574742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1575742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1576768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1577742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1578742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
157971207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
1580e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                            const AttributeList &Attr) {
1581341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  if (!isa<ObjCInterfaceDecl>(D)) {
1582341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
1583341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    return;
1584341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  }
1585341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian
1586e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1587e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  if (NumArgs > 0) {
1588e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1589e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    return;
1590e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  }
1591e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
159271207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
1593e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                 Attr.getRange(), S.Context));
1594e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian}
1595e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
15961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
15971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
15980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
15990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
16000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
16020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
16030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
16040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
16050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
16060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
16080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
16110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
16120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1613b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
16140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1615c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
16160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
16170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
16183b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Deprecated.Version)) {
16190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
16210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
16263b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Obsoleted.Version)) {
16270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
16343b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Deprecated.Version <= Obsoleted.Version)) {
16350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
16360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
16380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1641006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  StringRef Str;
1642006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  const StringLiteral *SE =
1643006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
1644006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  if (SE)
1645006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    Str = SE->getString();
1646006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian
1647768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context,
16480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
16490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
16500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1651b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1652006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                IsUnavailable,
1653006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                Str));
16540a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
16550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
16581731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
16596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1660bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16617a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
16626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
16636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1664bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16655cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1666fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
16673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
16686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1670bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1672cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1673bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1674c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1675cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1676c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1677cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1678c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1679cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1680c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1681cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
16826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
168308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
16846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1686bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1687768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type));
16886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
16896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
16911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1692d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1693d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
169487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1695883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1696d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1697d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1698d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
169987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
170087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
170187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1702d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1703d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
170487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1705d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
170687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1707d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1708d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1709d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1711d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1712d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1713d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1714d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1715d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1716d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1717d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1718d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1719d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1720d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1721d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1722d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1723d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1724d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1725d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1726d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
172787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1728d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1729d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1730d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1731f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1732f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1733f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1734f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1735f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1736f85e193739c953358c865005855253af4f68a497John McCall    return;
1737f85e193739c953358c865005855253af4f68a497John McCall  }
1738f85e193739c953358c865005855253af4f68a497John McCall
1739768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
1740f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1741d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1742d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
17441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
17451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
17460db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1747bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17480db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
17490db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
17500db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
17510db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
17520db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1753bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1754768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
17550db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
17560db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
17571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1758fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
17592b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1760fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1761fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1762162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1763fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1764fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
17656217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1766fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1767fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1768fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1769fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
17706b65d4a9cc5aed96a7f1a36e75dd9c4adb164e0bFariborz Jahanian  else
17719b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
1772768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
1773fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1774fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1775bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
17761b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1777f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
17782b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1779f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1780f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1781f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1782f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1783f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1784f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1785f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1786f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1787768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
1788f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1789f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
17901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1791bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1792fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
17933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
17949eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
17959eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1796bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17979eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
17983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
17999eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18009eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1801bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1802cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
180392e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
18049eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
18059eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1806fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
18073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
18089eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18099eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1810bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1811768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
18129eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
18139eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
18141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1815770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1816770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1817bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1818770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1819bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1820bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18213323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
1822770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
18237a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1824770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1825ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1826ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1827fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1829770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1830770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1831bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18323323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
1833fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1834fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1835770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1836770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
18373323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
18383323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
1839770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1840770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
18413323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
1842770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
18437a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1844770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1845ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1846ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1847fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1849770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1850770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1851770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1852bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18533323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
1854770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1855770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1856fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1857fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1858770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1859770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1860770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1861770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
186287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
18633323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
1864897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1865897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1866897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1867897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1868bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1869897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
18703bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1871770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1872bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
187387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1874770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
18753bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1876770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
18772f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1878a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
1879a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    if (!BD->isVariadic()) {
1880a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
1881a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      return;
1882a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    }
188387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
18842f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1885daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
188687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1887f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
18882f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
18893bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
18903bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
18912f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
18922f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1893ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
18942f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1895883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
18962f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
18972f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1898770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1899fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1900883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1901770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1902770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1903768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
1904f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1905770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1906770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
19071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1908026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
19091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1910026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1911026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1912f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1913026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1914883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1915026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1916026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1917bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1918f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1919f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1920f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1921f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1922f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1923f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1924f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1925f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1926f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1927f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1928f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1929f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1930768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
1931026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1932026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
19331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
193587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
193687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
194087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
194113c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    if (isa<CXXRecordDecl>(D)) {
194213c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
194313c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      return;
194413c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    }
194587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
194687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1947f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1948f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1949f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
195087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1951332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1952332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1953332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
195487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
19556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1957bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1958768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
19596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19626e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
19631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
19646e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19651731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
19666e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19676e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
19686e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
19690a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
19700a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
19710a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
19720a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
19730a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
1974def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1975bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
197690eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
1977def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
1978def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
1979c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1980883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
19816e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19826e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19836e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
19846e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1985768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
19866e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
19876e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
19891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
19906f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
19911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
19926f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
19936f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
19946f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
19956f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
19967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
19976f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1998ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1999ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
20006f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
20016f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
20026f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
20036f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
20046f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
20056f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
2006768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
2007cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
20086f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
20096f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
20106f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
201217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
20131731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
201417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
201517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
201617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
201717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
20187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2019797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
202017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
2021797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
202217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
202317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
20241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2025797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
2026bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2027a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2028a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2029a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2030797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2031797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
20321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2033a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2034a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2035a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2036a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2037a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2038a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
2039768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context,
2040f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
204117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
204217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
20436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2046831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
20473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
20486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2050b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
205187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2052b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2053ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2054b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2055768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2056b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
20576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2060232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2061831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
20623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2063232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2064232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2065bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
206687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2067b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2068ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2069b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2070768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2071b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2072232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2073232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
20741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2075232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
20761731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2077232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2078bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2079768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2080232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2081232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
20821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2083bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2084f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2085f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2086f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2087bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2088f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2089f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2090f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2091f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2092bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
209387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2094bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2095f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2096f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2097f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2098f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2099bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2100f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2101c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2102f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2103f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2104f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2105f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2106f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2107f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2108f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2109f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2110bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2111f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2112f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2113f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2114f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2115f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2116f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2117f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2118f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2119f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2120f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2121f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2122f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2123f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2124f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2125bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
212689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
212789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
212889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
212989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2130b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2131b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2132f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
213389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
213489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
213589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
213689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2137bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2138768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
2139223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
2140f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2141f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2142bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2143bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
21441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
21465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21471731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
214887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
21495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2150883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
21515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
215307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
215407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
215507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
215687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
215787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
21585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
215907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
21605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
21617a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
21625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2163ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2164ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
21655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
21665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
21675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2169bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
21715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
21725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
21735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2175bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21765b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
217807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
217907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
218007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
218107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
218207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
218307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
218407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
218507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
218607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
21875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
218887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2189bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
21915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
21925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
21935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
21946217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
21955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
21965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
21985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
21995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
220187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
22025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
22035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22056217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2208bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
22095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2211bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2213768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
221407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
22155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
22165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
22172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
22182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
22192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
22202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
22212b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
22223c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
22232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
22242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
22252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
22272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
22285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
22292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
22302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
22312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
22322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
22332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
22342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
22352b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
22362b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22372b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
22382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
22392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
22402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
2241cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2242cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
22432b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
22442b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2245bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2246bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
22473c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
22483c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22492b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
22502b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
22512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2252521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2253521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
22541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
22551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
2256521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
2257521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2258521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2259521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2260521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
226187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2262b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2263b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2264b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2265b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
226687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2267b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2268b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2269b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2270b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2271b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2272b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2273b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2274b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2275521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2276521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2277521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2278521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2279521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
22807a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2281b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2282521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2283521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2284521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2285521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2286521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2287521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2288521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2289521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
22909f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2291521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2292521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2293521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2294521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2295521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2296521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2297768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2298f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2299521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2300521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2301bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2302bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
23031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
23046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2305545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2306fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
23073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
23086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2311545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
23123c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
23136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
231687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2317fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2318883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
232207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
232307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
232487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
232587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
23266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
23276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
23296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
23312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
23322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
23332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
23342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
23352b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
23363c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23373c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
23383c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
23393c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2341fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
234201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
23436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
23477a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2348803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2349ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2350ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2351fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
23583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
23636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2364bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23654a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
23664a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
236707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
236807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
236907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
23704a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
23714a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
23724a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
23734a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
23741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
237687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
23776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2379085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2380fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2381fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2382085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2383085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
23842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2385390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2386390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2387803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2388390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2389fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2390fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
23916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2392bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
23936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
23946217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2395390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2396fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2397fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
23986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
24027a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2403803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2404ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2405ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2406fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
24073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
24126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
241387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
24146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
24156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
241687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
24176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
24223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
24232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
24246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2425fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2426fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
24276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
24306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2431fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
24323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2436b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2437b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
243887c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
243987c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2440b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2441b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2442b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2443b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2444b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2445b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2446b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2447b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2448ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis        f->setRange(Attr.getRange());
2449b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2450b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2451b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2452b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
2453768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format,
2454cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
24552b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
24566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
24591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
24606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
24611731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
24626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
24646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
24660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
246787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
24680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
24690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
24700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
247187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
24720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
24730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2474fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2475883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
24766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24795e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall  if (!RD->isCompleteDefinition()) {
2480bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
24810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
24820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
24840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
248517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
248617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
24870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
24880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
24890c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2491bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
24920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
24930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
249490cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2495bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
249690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
249790cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
24980c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24990c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2500bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
25020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
25030c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
25040c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
25050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
25060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
25070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
25080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2509bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
25100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2511bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
25120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
25130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
25140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2515bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
25160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
25170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2518bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2519bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2520bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
25216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2522768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
25236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
25271731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
25286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25291731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25307a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2531797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2532bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
25346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
25356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2536797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
25376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
253977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
254077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
254177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
254277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
254377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
254477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
254577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
254677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
2547768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
2548f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
25496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2553545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
25543c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
25556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2557bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2558bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2559bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2560bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
25616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2562545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2563768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0));
25644ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
25654ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
25664ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2567768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0));
25684ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
25694ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2570768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
25710b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  // FIXME: Handle pack-expansions here.
25720b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  if (DiagnoseUnexpandedParameterPack(E))
25730b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne    return;
25740b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne
25754ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
25764ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2577768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
25786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2580bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2581768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
2582cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
258349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
25844ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
25854ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
25864ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
258749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
258849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2589396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
25904ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
25914ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2592396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2593396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2594396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2595768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
2596cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2597cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2598768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
2599cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2600cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2601768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS));
2602cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
26036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2604fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2605d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2606bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2607fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2608bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2609bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2610bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
26111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2612fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2613fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2614fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2615fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
26161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2617fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
26181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2619fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2620fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2621fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
26220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2623fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2624fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2625210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
26265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2627fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2628fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2629210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2630210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2631fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2632fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2633fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
263473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2635210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2636fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
263773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
263873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
263973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
264073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
264173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
264273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
264373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
264473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
264573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
264673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
264773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
264873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
264973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
265073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
265173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
265273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2653fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2654fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2655fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2656fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2657210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
2658bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2659210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
2660bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
2661fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2662fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2663210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
2664bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2665fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2666fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2667fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2668fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2669162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2670fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2671fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2672fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2673fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2674fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2675768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
2676fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2677fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
267873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2679183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
268073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
268173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
26822ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
268373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
268473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
268573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
268673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
268773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
268873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
268973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
269073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
269173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2692390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2693390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2694390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2695390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2696f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2697f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2700fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
27013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
27043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2705fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
270773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
270873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
270973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
271073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27120b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2713fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2715fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2716fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
271773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
271873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
271973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
272073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2721fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2723fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27240b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2725fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2726fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2727fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2729fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
27300b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2731fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27320b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2733fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2734fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2735fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27360b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2737fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2738bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2739aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2740aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2741aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2743bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2744aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2745aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2746aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2747fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
274873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
274973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
275073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2751f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2752f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2753f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2754f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2755f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2756f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2757f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2758f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2759f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
276073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2761fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2762fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
276373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
276473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2765fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2767fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2768162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2769ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2770a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2771ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2772fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2773fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
27740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
27751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2776d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
27771731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2778d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2779e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
278087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2781d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2782883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2783d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2784d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2785bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2786768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
2787d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2788d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
27891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
27905bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
27911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
27925bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
27931731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2794bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
279587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
27965bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2797883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
27985bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
27995bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2800bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2801768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
28025bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
28035bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
28041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
28051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
28067255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
28071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28087255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
28107255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
281187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28127255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2813883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28147255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28157255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
28167255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2817768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
2818f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
28197255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
28207255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
28211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2822ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2823ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2824831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2825ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2826ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2827ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2828ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
282987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2830ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2831883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2832ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2833ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2834ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2835768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
2836ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2837ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2838ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2839ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2840ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2842ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2843ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2844ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2845ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2846ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2847ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2848ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
284987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2850ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2851883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2852ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2853ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2854ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2855768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
2856ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2857ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2858ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2859ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2860ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2862ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2863ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28641731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2865ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2866ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
286787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2868ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2869883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2870ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2871ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2872ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
287387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
28742c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2875723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
28762c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
28772c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
28782c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
28792c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
28802c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
28812c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
28822c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
28832c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
28842c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
28852c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
28862c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
28872c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2888768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
2889ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2890ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2891ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2892ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2893ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2895ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2896ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2898ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
28991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
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
2907768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
2908ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2909ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2910ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2911ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2912ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2914ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2915ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2917ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2919ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
292087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2921ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2922883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2923ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2924ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2925ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2926768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
2927ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2928ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2929ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2930ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2931ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
293326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
29341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
293526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2936bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
293787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2938c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
293926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2940883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
294126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
294226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2943bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
29440130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2945cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2946c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2947c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2948bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2949768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
295026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
295126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
29521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
295387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2954711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
295587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2956e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2957711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
295887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
2959711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2960e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
296187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
296287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
296387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2964711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2965711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2966711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
296787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2968e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
2969768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
2970e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2971e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
2972768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
2973e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2974f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
2975768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
297604633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2977e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
2978768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
2979e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
298052fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2981768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
298252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2983414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
298487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
2985414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
29865cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
298787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2988414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
298987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2990414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2991414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2992414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
29935f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2994414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2995414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2996414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2997414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2998414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2999414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
300087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
300187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3002414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3003414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3004414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
3005768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
3006414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3007e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
3008e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
3009e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
3010e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
3011e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
30121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
301356aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
3014768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3015f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
3016f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
3017711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
3018711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
3019711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3020711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3021831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
3022831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
3023831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
3024711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3025711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
3026711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3027ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
302855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3029414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3030414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3031711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
3032711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
3033711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
3034711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
3035711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
3036711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
3037414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
3038414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3039414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30405cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3041414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3042414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3043414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3044414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3045414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3046414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
30475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3048414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3049414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3050414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3051414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3052414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3053414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3054414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3055414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3056414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
30577530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("unexpected attribute kind");
3058711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3059711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3060711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3061711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3062711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
30631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
306487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3065711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3066711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
306787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3068711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3069711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
307087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
307187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
307287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3073ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3074ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
307555d3aaf9a537888734762170823daf750ea9036dEli Friedman
3076768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3077711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3078711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3079711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3080711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
308187c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
308287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3083711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3084711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
308587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
308687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
308787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3088711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3089711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3090711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
309187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
309255d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3093ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3094711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
309587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
309655d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
309787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3098711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
309955d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
310055d3aaf9a537888734762170823daf750ea9036dEli Friedman
3101bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
310287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
310355d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
310487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3105711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
310655d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
310755d3aaf9a537888734762170823daf750ea9036dEli Friedman
3108711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3109bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
311087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3111bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
311287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3113711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
311455d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
311555d3aaf9a537888734762170823daf750ea9036dEli Friedman
3116711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3117ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3118ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
31191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
31207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
31217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
31227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3123bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3124bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
31257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
312887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
31297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3130883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
31317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
31357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
31367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
31377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
31387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
31397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
31417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
31457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
31467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
31477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
31487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
31497b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
31507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
31527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
31537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
31547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3156768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
31577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
31587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
31597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
31607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
31617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
31627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
31637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31640744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3165b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3166b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3167b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3168c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
31696c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
31706c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isObjCObjectPointerType() ||
31716c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         S.Context.isObjCNSObjectType(type);
3172c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3173c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
31746c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
31756c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isPointerType() ||
31766c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         isValidSubjectOfNSAttribute(S, type);
3177c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3178c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
31791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
318087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3181c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
318287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3183768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3184c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3185c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3186c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3187c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
318887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3189c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3190c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3191c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3192c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3193c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3194c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3195c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3196c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
319787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3198768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3199c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3200c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3201c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3202c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3203768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3204c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3205768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3206c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3207c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
32091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
321087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
321187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3212768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3213c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3214c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3215c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3216768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3217c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3218c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
32201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3221b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3222c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3223bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
322487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3225c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
322687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3227831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
322887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
322987c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3230f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
323187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3232c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
32335dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
323487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3235768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3236883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3237b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3238b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3239bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3240c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3241c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
324287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
32437530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("invalid ownership attribute");
3244c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3245c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3246c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3247c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3248c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3249c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3250c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3251c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3252c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3253c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3254c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3255c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3256c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3257c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3258c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
325987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3260768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3261bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
32625dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3263bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
326487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3265b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3266b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
3267c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
3268768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3269c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3270c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
327131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
3272768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3273f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
327431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
327531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
3276768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3277f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
327831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3279b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
3280768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3281f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3282b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3283b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
3284768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3285f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3286b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3287b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3288b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3289b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3290dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3291dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3292dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3293dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3294dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3295dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3296dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!isa<ObjCMethodDecl>(method)) {
3297dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type)
3298dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc, loc) << attr.getName() << 13 /* methods */;
3299dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3300dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3301dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3302dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3303dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3304f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian
3305f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3306f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3307dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3308dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3309dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3310dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3311dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3312dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3313dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3314dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3315dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3316768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3317dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3318dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
33198dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
33208dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
33218dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
33228dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
33238dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << A.getName() << 0 /*function*/;
33248dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33258dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33268dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33278dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer);
33288dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33298dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
33308dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
33318dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33328dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
33338dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33348dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
33358dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33368dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
33378dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
33388dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
33398dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
33408dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
33418dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33428dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33438dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33448dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
33458dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33468dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
33478dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
33488dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33498dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
33508dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
33518dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33528dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
33538dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3354fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
3355fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
3356fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
3357fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
3358fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3359fe98da0fa352462c02db037360788748f95466f7John McCall      << Attr.getRange() << Attr.getName() << 14 /*struct */;
3360fe98da0fa352462c02db037360788748f95466f7John McCall  }
3361fe98da0fa352462c02db037360788748f95466f7John McCall
3362fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
3363fe98da0fa352462c02db037360788748f95466f7John McCall
3364fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
3365fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
3366fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
3367fe98da0fa352462c02db037360788748f95466f7John McCall  if (ParmName && S.getLangOptions().ObjC1) {
3368fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
3369fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
3370fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
3371fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
3372fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
3373fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
3374fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
3375fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
3376fe98da0fa352462c02db037360788748f95466f7John McCall      }
3377fe98da0fa352462c02db037360788748f95466f7John McCall    }
3378fe98da0fa352462c02db037360788748f95466f7John McCall  }
3379fe98da0fa352462c02db037360788748f95466f7John McCall
3380fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
3381fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
3382fe98da0fa352462c02db037360788748f95466f7John McCall}
3383fe98da0fa352462c02db037360788748f95466f7John McCall
33841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
33851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
338687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3387f85e193739c953358c865005855253af4f68a497John McCall
338887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3389768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    << Attr.getRange() << Attr.getName() << 12 /* variable */;
3390f85e193739c953358c865005855253af4f68a497John McCall}
3391f85e193739c953358c865005855253af4f68a497John McCall
33921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
33931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
339487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
339587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3396768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << 12 /* variable */;
3397f85e193739c953358c865005855253af4f68a497John McCall    return;
3398f85e193739c953358c865005855253af4f68a497John McCall  }
3399f85e193739c953358c865005855253af4f68a497John McCall
340087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3401f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3402f85e193739c953358c865005855253af4f68a497John McCall
3403f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3404f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
340587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3406f85e193739c953358c865005855253af4f68a497John McCall      << type;
3407f85e193739c953358c865005855253af4f68a497John McCall    return;
3408f85e193739c953358c865005855253af4f68a497John McCall  }
3409f85e193739c953358c865005855253af4f68a497John McCall
3410f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3411f85e193739c953358c865005855253af4f68a497John McCall
3412f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3413f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3414f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3415f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3416f85e193739c953358c865005855253af4f68a497John McCall
3417f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3418f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3419f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3420f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3421f85e193739c953358c865005855253af4f68a497John McCall    break;
3422f85e193739c953358c865005855253af4f68a497John McCall
3423f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3424f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3425f85e193739c953358c865005855253af4f68a497John McCall    break;
3426f85e193739c953358c865005855253af4f68a497John McCall
3427f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3428f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
342987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3430f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3431f85e193739c953358c865005855253af4f68a497John McCall    break;
3432f85e193739c953358c865005855253af4f68a497John McCall  }
3433f85e193739c953358c865005855253af4f68a497John McCall
343487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3435768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3436f85e193739c953358c865005855253af4f68a497John McCall}
3437f85e193739c953358c865005855253af4f68a497John McCall
3438f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
3439f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
344011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
344111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
344211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
344311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
344411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
344511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
344611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
344711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
34481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
344962ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
345011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
34511731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
345211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
34531731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
345411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
345511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
34565cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3457d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3458d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3459d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3460d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3461d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
34625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3463d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3464d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3465d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3466d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3467d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3468d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3469d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3470d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3471d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3472d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3473d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3474d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3475d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3476d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3477d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3478d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
34795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3480f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3481f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3482f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3483f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3484d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3485d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3486d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3487d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3488d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3489d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3490d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3491d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3492d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3493d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3494d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
349511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
3496768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
349711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3498d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
349911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3500f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3501f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3502b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
35030744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
35040744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
35050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
35061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
350860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
35091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
35101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
35111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
351260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
351360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
351460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
351560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3516e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
35171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3519803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
35201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break;
35211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
3522857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
35231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3524803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3525207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3526ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
35276e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
35284211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
35294211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3530bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3531bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3532803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
353360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
353460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
353560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
353660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
353760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
353860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
35391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
35401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3541bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
35421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3543b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
35441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
35451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
35461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3547bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
35481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
35491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
35501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
35511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
35521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
35531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
35543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
35551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
35563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
35571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
35581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
35591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
35601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
35617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
35621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
35637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
35641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
35651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
35661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
35671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
35681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3570dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3571dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
35721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
35731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
35741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
35751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
35761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
35771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3578b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3579b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
35801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3581f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
35821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3583f85e193739c953358c865005855253af4f68a497John McCall
3584dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3585dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3586dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3587fe98da0fa352462c02db037360788748f95466f7John McCall  case AttributeList::AT_ns_bridged:
3588fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
3589fe98da0fa352462c02db037360788748f95466f7John McCall
35908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_audited_transfer:
35918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_unknown_transfer:
35928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
35938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3594b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3595c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
35961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3597c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
35981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3599c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3600c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
360131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
360231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3603b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3604b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
36051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3606b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
36076f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
36081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
36096f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3610521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
36111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3612521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
36131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
36141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break;
36151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
36161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3617742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  case AttributeList::AT_arc_weakref_unavailable:
3618742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3619742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
362071207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  case AttributeList::AT_objc_requires_property_definitions:
362171207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
3622e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    break;
36231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
3624f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  case AttributeList::AT_returns_twice:
3625f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
3626f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
36271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
36281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
36291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3630026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
36311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
36321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
36331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3634803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
36351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3636803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
36370db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
36381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
36390db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3640d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
36411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3642d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
36431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break;
36441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
36451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
36461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
36471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
36481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
36491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
36501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
36511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3652bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
365305f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
365405f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
36557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
36561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
36577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
365804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
365904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
366004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3661f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
366252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3663414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
36641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
366504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3666f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
36671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3668f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
366911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
36701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
367111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3672fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3673fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3674fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3675fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3676fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3677fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3678fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3679fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3680fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3681fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3682fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3683fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3684fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3685fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3686fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3687fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3688fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3689db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3690db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3691db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3692db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3693db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3694db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3695db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3696db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3697db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3698db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3699db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3700db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3701db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3702db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3703db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3704db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3705db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3706db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3707db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3708db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3709db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3710db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3711db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3712db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3713db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3714db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3715db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3716db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3717db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3718db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3719db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3720db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3721db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3722db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3723db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3724db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3725db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3726db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3727db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3728fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3729803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
373082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
373182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
373282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
37337d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
37347d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3735803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3736803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3737803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3738803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
373960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
374060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
374160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
374260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
37431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
37441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
374560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
374660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
374760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
374860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
374960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
375060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
375160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
375260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
375360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
37541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
375560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
375660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
37571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
375860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
375960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3760803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3761803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3762f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
376360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
376460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
376511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
37661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
376711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
376811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
376911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
377011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
377111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
377260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
377311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3774dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
377511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3776803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3777803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3778803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
37795f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access
37805f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier.
37815f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
37825f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          const AttributeList *AttrList) {
37835f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
37845f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    if (l->getKind() == AttributeList::AT_annotate) {
37855f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      handleAnnotateAttr(*this, ASDecl, *l);
37865f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    } else {
37875f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
37885f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      return true;
37895f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    }
37905f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  }
37915f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
37925f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  return false;
37935f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen}
37945f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
3795e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
3796e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
3797e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
3798e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
3799e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
3800e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
3801e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
3802e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3803e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
3804e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
3805e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3806e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
3807e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
3808e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3809e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
3810e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
3811e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3812e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3813e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
3814e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
3815e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
3816e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
3817e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
3818e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
3819e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
3820e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
3821e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3822e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3823e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3824e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
3825900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
3826900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
38277b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3828e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3829e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3830900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
3831900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
3832900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
3833900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
3834900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
3835900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3836900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
3837900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
3838900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
3839900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
3840900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
3841900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
3842900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
3843900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3844900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
3845c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3846900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3847900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
3848900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
3849900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
3850900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
3851900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
3852900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
3853900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
3854900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
3855900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
3856900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
3857900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
38584278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
3859b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3860e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3861e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3862ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3863a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
386416573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
386516573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3866b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3867b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3868c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3869b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3870e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3871e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3872e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3873e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3874e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3875e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
38767b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3877c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3878c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3879c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3880c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3881900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
3882cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3883cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3884cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3885c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3886c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3887c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3888c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3889c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3890c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3891c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3892c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3893cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3894e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3895e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3896e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
38970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
38980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
38990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
390060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
390160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3902d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3903d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
390431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
390531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
390631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
390731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
390831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
390931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
391031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
391131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
391231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
391331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
391431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
391531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3916d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3917e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3918e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3919e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3920e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
39210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
39227f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
392360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3924bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
39250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
39260744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
39270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
39280744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
39290744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
39300744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
393160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3932bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
39330744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
39340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
393560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
39360744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
393754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3938f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3939f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3940f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3941f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3942f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3943a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
3944a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
3945a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
3946f85e193739c953358c865005855253af4f68a497John McCall    return false;
3947f85e193739c953358c865005855253af4f68a497John McCall
3948f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3949f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3950f85e193739c953358c865005855253af4f68a497John McCall}
3951f85e193739c953358c865005855253af4f68a497John McCall
3952f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
3953f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3954f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
3955f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
3956f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3957f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
3958f85e193739c953358c865005855253af4f68a497John McCall    return;
3959f85e193739c953358c865005855253af4f68a497John McCall  }
3960175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian  if (S.getLangOptions().ObjCAutoRefCount)
3961175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
3962175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // FIXME. we may want to supress diagnostics for all
3963175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // kind of forbidden type messages on unavailable functions.
3964175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
3965175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag.getForbiddenTypeDiagnostic() ==
3966175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
3967175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
3968175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
3969175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
3970175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
3971f85e193739c953358c865005855253af4f68a497John McCall
3972f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3973f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3974f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
3975f85e193739c953358c865005855253af4f68a497John McCall}
3976f85e193739c953358c865005855253af4f68a497John McCall
3977eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3978eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3979eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3980eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3981eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3982eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3983eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3984eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3985eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3986eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3987eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3988eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3989eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3990eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3991eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3992eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3993eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3994eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3995eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3996eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3997eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
399854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
399954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4000eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
4001eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
4002eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
400354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4004eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
4005eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
4006eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
4007eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
400854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4009eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
4010eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
401154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4012eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
4013eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
4014eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
401558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
40162f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
40172f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
4018a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis  if (decl && !decl->isInvalidDecl()) {
4019eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
4020eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
40212f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
40222f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
40232f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
40242f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
40252f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
4026eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
4027eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
4028eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
40292f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
40302f514480c448708ec382a684cf5e035d3a827ec8John McCall
4031eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
40322f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
4033eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
40342f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
40352f514480c448708ec382a684cf5e035d3a827ec8John McCall
40362f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
4037eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
40382f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
4039f85e193739c953358c865005855253af4f68a497John McCall
4040f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
4041f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
4042f85e193739c953358c865005855253af4f68a497John McCall        break;
404354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
404454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
404554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
404654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
404758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
4048eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
404929233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
405058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
4051eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
40522f514480c448708ec382a684cf5e035d3a827ec8John McCall}
40532f514480c448708ec382a684cf5e035d3a827ec8John McCall
40542f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
40552f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
40560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
40572f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
4058c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    // A category implicitly has the availability of the interface.
4059c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4060c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis      return CatD->getClassInterface()->isDeprecated();
40612f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
40622f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
40632f514480c448708ec382a684cf5e035d3a827ec8John McCall}
40642f514480c448708ec382a684cf5e035d3a827ec8John McCall
40659c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
40662f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
40672f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
40682f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
40692f514480c448708ec382a684cf5e035d3a827ec8John McCall
40702f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4071ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
4072c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
4073ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
4074ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
4075c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
4076c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
4077ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
407854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
407954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
40805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
40818e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
408289ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
408354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4084eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
4085eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
408654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
408754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
408854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
408954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
40903a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
409154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4092ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
4093c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
4094c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
40958e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
4096743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
40978e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
409889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
40998e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
410089ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
410189ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
41028e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
410354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4104