SemaDeclAttr.cpp revision 3a387441ae339363ee5b254658f295e97bd9e913
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>()) {
7632f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_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>()) {
7702f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_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)
808a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
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())).
821a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
822a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
823a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
824a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
825a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
826f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
827f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
828857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
829857e918a8a40deb128840308a318bf623d68295fTed Kremenek
830d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
83168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
83268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
83368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
83468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
83568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
83668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
83768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
83868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
83968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
84068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
84168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
84268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
84368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
84468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
8451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
846bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
847bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
84887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
849fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
850883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
851eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
852eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
853bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
85407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
85507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
85687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
85787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
858eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
859eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
8605f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
861bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
862eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
863eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
864bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
865bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
866eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
8677a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
868eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
869ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
870ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
871fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
872fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
873eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
874eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
875bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
876eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
877bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
878eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
879fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
88030bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
881eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
882eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
883bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
884465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
88507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
88607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
88707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
88807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
88907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
89007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
89107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
89207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
89307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
894eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
895eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
89687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
897d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
89868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
899dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
900eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
901c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
902fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
9037fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
904eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
905bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
906eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
907eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
908bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
909bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
910bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
9117fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
91287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
91387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
914d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
915dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
916d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
91746bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
918bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
919ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
92060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
92160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
92260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
92360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
92460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
9257fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
92660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
927eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
9287fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
9297fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
9307fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
931dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
932768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
933cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
934eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
935eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
9361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
937dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
938dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
939dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
940dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
941dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
942dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
9432a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
9442a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
945dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
946dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
947dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
948dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
949dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
950dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
951dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
952cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
9532a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
9542a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
955cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
956dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
959dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9602a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9612a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
962cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
963dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
964dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
965dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
966dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9672a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9682a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
969cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
970dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
971dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
972dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
973dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
974dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
9752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
9762a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
9772a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
9782a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
979dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
980dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
98187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
982883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
983883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
986dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
98707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
98807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
98987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
99087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
991dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
993dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
994dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
995dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
997dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
9985f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
999dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10002a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
10012a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1002dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10037a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1004dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1008dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1009dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1010dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1011dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1012dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1013dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1014dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1015dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1016dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1019dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
102007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
102107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
102207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
102307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
102407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
102507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
102607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
102707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
102807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1030cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1031cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1032dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
103387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1034dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1035dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1036dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1037cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1040dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1041dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1042dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1043dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1044cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1045dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1046dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
10477a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1048dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1049dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1052dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1053dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1055dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1056dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1057dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1058dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
10592a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
10602a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
1061dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1062dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1063dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1064cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
106587c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
106687c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1067cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1068cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1069cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1070cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1071cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1072cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1073cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1074dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1075dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1077dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1078dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1079dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1080dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1081dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1082dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1083dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1084cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1085cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1086cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1087cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1088dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1089cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
109087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1091cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1092dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1093dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1094332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1095332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1096332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1097332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1098332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1099332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1100332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1101332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1102332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1103332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1104332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1105332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1106332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1107332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1108332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1109332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1110332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
111111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
111211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
111311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
111511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
111611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
111711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
111811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
111911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
112011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
112187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1122332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1123883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1124332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1125332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1126332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
112787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1128332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
112911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
113011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
113111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
113211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
113311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
113411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
113511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
113611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
113711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
113811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
113987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
11407a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
11417a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1142332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
11437a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
114411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
114511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
114611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
114711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
114811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
114911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
115011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
115211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
115711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
115811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
115911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
116011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
116111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
116211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1164332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1165332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
116611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
117111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
117311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
11747a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
117711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11785cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
118011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
118111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
118211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
118311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
118411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1185768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1186f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
118711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
118811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1189768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
119011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
119111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
11936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1194545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
11953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1198bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11997a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
12006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
12016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1202bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12035cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1204fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
12066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1208bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1209bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1210f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1211f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1212f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1213f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
12146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1215bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1216768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1217f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
12186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1221dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
12221731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1223dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1224dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
122587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1226dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1227883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1228dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1229dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1230dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1231768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1232dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1233dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
12341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
12351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1236dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1237831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
12383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1239af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1240af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
12415bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
124287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
12435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1244883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
12455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
12465bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1247bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1248768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1249af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1250af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
12511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1252dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1253831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
125476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
125576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
125676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
12571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
125887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
12602cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1261768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
12622cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
12632cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1264fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1265fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
12662cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
126776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
126876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
12691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
127034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
12711731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
127234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
127334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1274768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
127534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
127634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
12771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
127856aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
127987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1280768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1281722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1282722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1283883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1284a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1285a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
128756aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
128887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1289768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1290722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1291722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1292883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1293a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1294a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
12951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
129687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1297711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1298711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1299711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
130087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1301711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1302883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1303711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1305711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1306768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1307711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1308711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1309711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1310831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1311711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1312711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1313711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1314711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1315711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1316711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1317b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1318b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
13201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1321b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1322b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1323b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1324b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
13261731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1327b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
132887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
132987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
13303ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
13313ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1332e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1333e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1334b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1335883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1336b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
133719c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
13386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1339b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1340768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
13416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
134335cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
13441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
134535cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
134635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
134735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1348f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1349f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1350f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1351f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1352f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
135335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
135435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
135535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
135635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
135735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
135835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
135935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
136035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
136135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
136235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
136335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
136435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
136635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
136735cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
136887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
136935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1370883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
137135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
137235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
137335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
137535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
137635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
137735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
137835cc9627340b15232139b3c43fcde5973e7fad30John Thompson
137987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
138001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
138101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
138201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
138301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
138401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
138501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
138601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
138701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
138801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
138901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
139001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
139101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1392f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1393f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
139401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
139501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
139601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
139701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
139801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
139901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
140001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1401768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
140235cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
140335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
14041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
140587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1406bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1407883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1408bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1409bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1410bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1411bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1412bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
14131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
141473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1415831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
141773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
141873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1419bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
142087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
142187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1422fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1423883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
142473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
142573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1426bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1427768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
142873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
142973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1430f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1431f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1432f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1433f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1434f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1435f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1436f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1437f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1438f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1439f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1440f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1441f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1442f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1443f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1444f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1445f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1446f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
14471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1448b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1449831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1450b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1451b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1452b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1453bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
145487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1455186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1456b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1457b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1458b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
145987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1460b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1461883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1462b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1463b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1464bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1465768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1466b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1467b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
14681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1470bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1471bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
14723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1473bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
14763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
14777a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
14783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1479ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1480ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1481fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
14833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
14843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
14853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
14863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1487bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
148887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1489fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1490883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
14913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
14923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
14933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1494768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1495f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
14963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
14973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
14981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1500bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1501bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
15023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1503bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
15063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
15077a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
15083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1509ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1510ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1511fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15123c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
15133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1517bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
151887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1519fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1520883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1524768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1525f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
15263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1529951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1530951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1531bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1532c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1533c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1534951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1535c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
15365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1537951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1538951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1539c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1540951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1541951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1542c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1543c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1544951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
15456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1546bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1547768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str));
15486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1551951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1552951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1553bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1554bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1555bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1556951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1557c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
15585f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1559951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1560951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1561c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1562951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1563c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1564c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1565c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1566951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1567c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1568768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str));
1569bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1570bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1571742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1572742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1573742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1574742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1575742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1576742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1577742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1578742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1579742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1580768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1581742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1582742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
15831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
15841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
15850a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
15860a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
15870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
15890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
15900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
15910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
15920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
15930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
15950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
15960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
15970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
15980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
15990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1600b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
16010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1602c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
16030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
16040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
16053b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Deprecated.Version)) {
16060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
16080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
16133b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Obsoleted.Version)) {
16140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
16213b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Deprecated.Version <= Obsoleted.Version)) {
16220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
16230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
16250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1628768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context,
16290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
16300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
16310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1632b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1633b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                IsUnavailable));
16340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
16350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
16381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
16396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1640bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16417a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
16426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
16436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1644bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16455cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1646fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
16473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
16486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1650bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16515f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1652cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1653bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1654c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1655cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1656c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1657cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1658c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1659cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1660c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1661cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
16626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
166308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
16646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1666bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1667768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type));
16686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
16696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
16711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1672d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1673d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
167487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1675883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1676d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1677d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1678d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
167987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
168087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
168187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1682d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1683d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
168487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1685d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
168687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1687d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1688d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1689d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
16905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1691d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1692d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1693d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1694d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1695d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1696d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1697d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1698d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1699d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1700d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1701d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1702d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1703d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1704d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1705d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1706d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
170787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1708d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1709d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1710d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1711f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1712f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1713f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1714f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1715f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1716f85e193739c953358c865005855253af4f68a497John McCall    return;
1717f85e193739c953358c865005855253af4f68a497John McCall  }
1718f85e193739c953358c865005855253af4f68a497John McCall
1719768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
1720f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1721d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1722d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
17241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
17251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
17260db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1727bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17280db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
17290db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
17300db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
17310db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
17320db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1733bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1734768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
17350db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
17360db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
17371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1738fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
17392b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1740fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1741fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1742162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1743fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1744fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
17456217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1746fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1747fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1748fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1749fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1750768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
1751fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1752fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1753bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
17541b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1755f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
17562b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1757f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1758f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1759f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1760f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1761f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1762f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1763f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1764f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1765768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
1766f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1767f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
17681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1769bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1770fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
17713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
17729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
17739eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1774bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
17763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
17779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
17789eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1779bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1780cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
178192e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
17829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
17839eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1784fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
17853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
17869eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
17879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1788bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1789768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
17909eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
17919eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
17921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1793770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1794770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1795bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1796770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1797bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1798bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17993323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
1800770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
18017a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1802770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1803ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1804ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1805fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1807770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1808770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1809bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18103323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
1811fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1812fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1813770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1814770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
18153323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
18163323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
1817770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1818770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
18193323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
1820770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
18217a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1822770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1823ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1824ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1825fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1827770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1828770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1829770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1830bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18313323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
1832770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1833770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1834fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1835fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1836770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1837770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1838770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1839770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
184087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
18413323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
1842897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1843897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1844897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1845897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1846bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1847897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
18483bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1849770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1850bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
185187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1852770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
18533bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1854770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
18552f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
185687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (isa<BlockDecl>(D)) {
1857bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1858bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
18592f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
186087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
18612f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1862daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
186387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1864f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
18652f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
18663bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
18673bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
18682f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
18692f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1870ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
18712f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1872883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
18732f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
18742f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1875770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1876fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1877883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1878770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1879770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1880768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
1881f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1882770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1883770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
18841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1885026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
18861731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1887026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1888026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1889f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1890026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1891883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1892026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1893026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1894bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1895f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1896f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1897f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1898f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1899f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1900f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1901f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1902f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1903f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1904f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1905f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1906f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1907768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
1908026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1909026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
19101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
191287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
191387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19166e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
191787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
191887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
191987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1920f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1921f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1922f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
192387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1924332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1925332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1926332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
192787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
19286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1930bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1931768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
19326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
19361731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
19376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
19396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19406e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
19416e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
19420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
19430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
19440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
19450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
19460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
1947def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1948bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
1949def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor              isa<ObjCInterfaceDecl>(D))) {
1950def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
1951def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
1952c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1953883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
19546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
19566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
19576e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1958768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
19596e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
19606e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
19611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
19621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
19636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
19641731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
19656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
19666f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
19676f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
19686f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
19697a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
19706f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1971ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1972ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
19736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
19746f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
19756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
19766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
19776f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
19786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1979768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
1980cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
19816f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
19826f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
19836f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
19841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
198517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
19861731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
198717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
198817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
198917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
199017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
19917a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1992797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
199317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1994797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
199517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
199617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
19971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1998797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1999bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2000a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2001a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2002a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2003797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2004797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
20051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2006a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2007a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2008a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2009a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2010a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2011a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
2012768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context,
2013f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
201417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
201517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
20166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2019831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
20203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
20216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2023b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
202487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2025b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2026ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2027b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2028768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2029b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
20306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2033232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2034831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
20353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2036232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2037232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2038bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
203987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2040b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2041ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2042b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2043768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2044b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2045232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2046232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
20471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2048232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
20491731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2050232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2051bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2052768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2053232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2054232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
20551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2056bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2057f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2058f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2059f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2060bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2061f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2062f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2063f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2064f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2065bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
206687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2067bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2068f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2069f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2070f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2071f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2072bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2073f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2074c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2075f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2076f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2077f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2078f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2079f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2080f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2081f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2082f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2083bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2084f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2085f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2086f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2087f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2088f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2089f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2090f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2091f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2092f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2093f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2094f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2095f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2096f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2097f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2098bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
209989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
210089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
210189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
210289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2103b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2104b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2105f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
210689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
210789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
210889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
210989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2110bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2111768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
2112223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
2113f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2114f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2115bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2116bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
21171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
21195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21201731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
212187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
21225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2123883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
21245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
212607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
212707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
212807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
212987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
213087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
21315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
213207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
21335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
21347a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
21355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2136ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2137ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
21385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
21395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
21405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2142bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
21445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
21455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
21465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
21475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2148bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2150bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
215107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
215207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
215307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
215407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
215507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
215607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
215707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
215807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
215907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
21605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
216187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2162bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
21645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
21655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
21665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
21676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
21685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
21695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
21715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
21725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
217487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
21755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
21765b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
21775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
21786217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
21795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
21805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2181bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
21825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
21835b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2184bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2185bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2186768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
218707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
21885b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
21895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
21902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
21912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
21922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
21932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
21942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
21953c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
21962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
21972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
21982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
21992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
22002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
22015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
22022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
22032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
22042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
22052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
22062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
22072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
22082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
22092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
22102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
22112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
22122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
22132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
2214cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2215cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
22162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
22172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2218bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2219bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
22203c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
22213c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
22222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
22232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
22242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2225521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2226521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
22271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
22281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
2229521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
2230521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2231521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2232521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2233521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
223487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2235b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2236b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2237b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2238b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
223987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2240b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2241b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2242b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2243b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2244b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2245b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2246b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2247b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2248521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2249521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2250521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2251521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2252521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
22537a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2254b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2255521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2256521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2257521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2258521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2259521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2260521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2261521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2262521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
22639f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2264521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2265521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2266521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2267521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2268521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2269521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2270768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2271f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2272521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2273521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2274bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2275bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
22761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
22776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2278545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2279fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
22803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
22816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2284545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
22853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
22866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
228987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2290fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2291883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
229507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
229607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
229787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
229887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
22996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
23006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
23026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
23042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
23052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
23062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
23072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
23082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
23093c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23103c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
23113c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
23123c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2314fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
231501eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
23166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
23207a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2321803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2322ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2323ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2324fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2330fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
23313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
23326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
23366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2337bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23384a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
23394a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
234007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
234107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
234207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
23434a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
23444a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
23454a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
23464a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
23471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
234987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
23506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2352085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2353fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2354fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2355085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2356085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
23572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2358390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2359390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2360803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2361390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2362fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2363fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
23646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2365bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
23666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
23676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2368390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2369fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2370fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
23716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
23757a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2376803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2377ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2378ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2379fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
23816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
23856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
238687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
23876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
23886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
238987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
23906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
23916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
23926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
23953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
23962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
23976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2398fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2399fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
24006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
24036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2404fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
24053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2409b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2410b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
241187c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
241287c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2413b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2414b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2415b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2416b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2417b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2418b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2419b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2420b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2421ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis        f->setRange(Attr.getRange());
2422b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2423b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2424b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2425b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
2426768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format,
2427cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
24282b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
24296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
24321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
24336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
24341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
24356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24361731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
24376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
24390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
244087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
24410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
24420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
24430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
244487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
24450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
24460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2447fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2448883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
24496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
2453bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
24540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
24550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
24570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
245817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
245917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
24600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
24610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
24620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2464bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
24650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
24660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
246790cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2468bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
246990cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
247090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
24710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
24720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2473bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
24740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
24750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
24760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
24770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
24780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
24790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
24800c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
24810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2482bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
24830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2484bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
24850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
24860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
24870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2488bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
24890c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
24900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2491bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2492bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2493bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
24946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2495768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
24966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
25001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
25016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25037a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2504797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2505bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
25076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
25086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2509797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
25106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
251277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
251377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
251477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
251577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
251677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
251777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
251877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
251977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
2520768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
2521f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
25226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
25256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2526545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
25273c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
25286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2530bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2531bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2532bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2533bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
25346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2535545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2536768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0));
25374ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
25384ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
25394ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2540768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0));
25414ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
25424ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2543768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
25444ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
25454ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2546768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
25476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2549bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2550768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
2551cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
255249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
25534ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
25544ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
25554ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
255649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
255749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2558396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
25594ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
25604ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2561396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2562396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2563396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2564768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
2565cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2566cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2567768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
2568cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2569cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2570768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS));
2571cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
25726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2573fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2574d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2575bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2576fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2577bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2578bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2579bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
25801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2581fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2582fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2583fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2584fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
25851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2586fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
25871731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2588fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2589fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2590fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
25910b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2592fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2593fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2594210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
25955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2596fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2597fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2598210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2599210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2600fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2601fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2602fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
260373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2604210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2605fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
260673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
260773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
260873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
260973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
261073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
261173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
261273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
261373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
261473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
261573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
261673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
261773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
261873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
261973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
262073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
262173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2622fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2623fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2624fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2625fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2626210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
2627bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2628210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
2629bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
2630fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2631fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2632210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
2633bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2634fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2635fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2636fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2637fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2638162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2639fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2640fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2641fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2642fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2643fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2644768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
2645fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2646fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
264773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2648183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
264973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
265073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
26512ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
265273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
265373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
265473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
265573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
265673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
265773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
265873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
265973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
266073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2661390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2662390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2663390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2664390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2665f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2666f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2667fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2668fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2669fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
26703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2671fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2672fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
26733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2675fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
267673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
267773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
267873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
267973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2680fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
26810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2682fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
26830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2684fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2685fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
268673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
268773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
268873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
268973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2690fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
26910b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2692fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
26930b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2694fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2695fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2696fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
26970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
26990b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2700fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2704fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
27050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2707bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2708aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2709aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2710aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2712bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2713aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2714aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2715aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2716fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
271773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
271873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
271973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2720f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2721f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2722f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2723f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2724f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2725f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2726f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2727f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2728f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
272973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2730fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2731fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
273273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
273373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2734fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2735fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2736fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2737162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2738ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2739a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2740ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2741fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
27430744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
27441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2745d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
27461731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2747d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2748e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
274987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2750d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2751883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2752d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2753d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2754bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2755768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
2756d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2757d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
27581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
27595bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
27601731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
27615bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
27621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2763bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
276487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
27655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2766883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
27675bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
27685bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2769bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2770768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
27715bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
27725bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
27731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
27741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
27757255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
27761731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
27777255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
27781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
27797255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
278087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
27817255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2782883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
27837255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
27847255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
27857255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2786768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
2787f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
27887255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
27897255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
27901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2791ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2792ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2793831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2794ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2795ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2796ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2797ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
279887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2799ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2800883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2801ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2802ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2803ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2804768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
2805ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2806ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2807ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2808ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2809ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2811ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2812ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2813ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2814ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2815ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2816ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2817ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
281887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2819ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2820883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2821ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2822ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2823ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2824768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
2825ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2826ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2827ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2828ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2829ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2831ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2832ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28331731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2834ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2835ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
283687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2837ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2838883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2839ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2840ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2841ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
284287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
28432c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2844723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
28452c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
28462c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
28472c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
28482c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
28492c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
28502c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
28512c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
28522c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
28532c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
28542c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
28552c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
28562c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2857768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
2858ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2859ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2860ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2861ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2862ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2864ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2865ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2867ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
28681731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2869ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
287087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2871ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2872883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2873ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2874ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2875ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2876768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
2877ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2878ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2879ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2880ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2881ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
28821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2883ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2884ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
28851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2886ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
28871731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2888ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
288987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2890ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2891883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2892ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2893ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2894ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2895768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
2896ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2897ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2898ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2899ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2900ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
290226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
29031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
290426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2905bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
290687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2907c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
290826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2909883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
291026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
291126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2912bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
29130130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2914cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2915c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2916c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2917bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2918768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
291926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
292026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
29211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
292287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2923711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
292487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2925e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2926711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
292787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
2928711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2929e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
293087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
293187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
293287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2933711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2934711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2935711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
293687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2937e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
2938768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
2939e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2940e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
2941768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
2942e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2943f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
2944768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
294504633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2946e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
2947768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
2948e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
294952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2950768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
295152fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2952414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
295387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
2954414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
29555cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
295687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2957414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
295887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2959414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2960414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2961414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
29625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2963414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2964414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2965414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2966414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2967414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2968414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
296987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
297087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2971414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2972414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2973414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2974768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
2975414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2976e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2977e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2978e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2979e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2980e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2981e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
29821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
298356aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
2984768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
2985f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2986f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2987711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2988711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2989711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2990711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2991831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
2992831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2993831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
2994711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2995711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2996711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2997ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
299855d3aaf9a537888734762170823daf750ea9036dEli Friedman
2999414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3000414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3001711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
3002711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
3003711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
3004711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
3005711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
3006711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
3007414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
3008414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3009414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30105cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3011414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3012414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3013414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3014414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3015414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3016414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
30175f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3018414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3019414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3020414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3021414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3022414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3023414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3024414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3025414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3026414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3027711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
3028711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3029711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3030711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3031711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3032711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
30331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
303487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3035711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3036711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
303787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3038711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3039711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
304087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
304187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
304287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3043ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3044ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
304555d3aaf9a537888734762170823daf750ea9036dEli Friedman
3046768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3047711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3048711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3049711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3050711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
305187c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
305287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3053711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3054711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
305587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
305687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
305787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3058711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3059711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3060711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
306187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
306255d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3063ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3064711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
306587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
306655d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
306787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3068711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
306955d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
307055d3aaf9a537888734762170823daf750ea9036dEli Friedman
3071bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
307287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
307355d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
307487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3075711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
307655d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
307755d3aaf9a537888734762170823daf750ea9036dEli Friedman
3078711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3079bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
308087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3081bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
308287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3083711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
308455d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
308555d3aaf9a537888734762170823daf750ea9036dEli Friedman
3086711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3087ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3088ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
30891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
30907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
30917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
30927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3093bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3094bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
30957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
30967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
30977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
309887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
30997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3100883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
31017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
31057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
31067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
31077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
31087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
31097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
31117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
31127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
31157b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
31167b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
31177b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
31187b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
31197b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
31207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
31217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
31227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
31237b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
31247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
31257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3126768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
31277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
31287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
31297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
31307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
31317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
31327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
31337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
31340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3135b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3136b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3137b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3138c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
3139c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
3140c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3141c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
3142c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
3143c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3144c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
31451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
314687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3147c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
314887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3149768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3150c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3151c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3152c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3153c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
315487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3155c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3156c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3157c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3158c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3159c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3160c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3161c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3162c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
316387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3164768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3165c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3166c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3167c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3168c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3169768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3170c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3171768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3172c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3173c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
31741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
31751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
317687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
317787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3178768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3179c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3180c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3181c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3182768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3183c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3184c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
31851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
31861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3187b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3188c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3189bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
319087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3191c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
319287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3193831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
319487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
319587c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3196f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
319787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3198c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
31995dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
320087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3201768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3202883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3203b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3204b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3206c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3207c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
320887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3209c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
3210c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3211c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3212c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3213c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3214c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3215c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3216c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3217c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3218c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3219c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3220c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3221c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3222c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3223c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3224c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
322587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3226768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3227bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
32285dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3229bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
323087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3231b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3232b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
3233c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
3234768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3235c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3236c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
323731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
3238768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3239f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
324031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
324131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
3242768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3243f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
324431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3245b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
3246768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3247f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3248b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3249b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
3250768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3251f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3252b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3253b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3254b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3255b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3256dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3257dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3258dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3259dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3260dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3261dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3262dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!isa<ObjCMethodDecl>(method)) {
3263dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type)
3264dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc, loc) << attr.getName() << 13 /* methods */;
3265dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3266dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3267dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3268dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3269dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3270f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian
3271f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3272f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3273dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3274dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3275dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3276dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3277dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3278dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3279dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3280dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3281dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3282768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3283dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3284dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
32858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
32868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
32878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
32888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
32898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << A.getName() << 0 /*function*/;
32908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
32918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
32928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
32938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer);
32948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
32958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
32968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
32978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
32988dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
32998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
33018dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33028dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
33038dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
33048dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
33058dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
33068dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
33078dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
33088dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33098dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
33108dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
33118dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
33128dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
33138dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
33148dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
33158dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
33168dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
33178dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
33188dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
33198dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3320fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
3321fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
3322fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
3323fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
3324fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3325fe98da0fa352462c02db037360788748f95466f7John McCall      << Attr.getRange() << Attr.getName() << 14 /*struct */;
3326fe98da0fa352462c02db037360788748f95466f7John McCall  }
3327fe98da0fa352462c02db037360788748f95466f7John McCall
3328fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
3329fe98da0fa352462c02db037360788748f95466f7John McCall
3330fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
3331fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
3332fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
3333fe98da0fa352462c02db037360788748f95466f7John McCall  if (ParmName && S.getLangOptions().ObjC1) {
3334fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
3335fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
3336fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
3337fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
3338fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
3339fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
3340fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
3341fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
3342fe98da0fa352462c02db037360788748f95466f7John McCall      }
3343fe98da0fa352462c02db037360788748f95466f7John McCall    }
3344fe98da0fa352462c02db037360788748f95466f7John McCall  }
3345fe98da0fa352462c02db037360788748f95466f7John McCall
3346fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
3347fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
3348fe98da0fa352462c02db037360788748f95466f7John McCall}
3349fe98da0fa352462c02db037360788748f95466f7John McCall
33501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
33511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
335287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3353f85e193739c953358c865005855253af4f68a497John McCall
335487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3355768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    << Attr.getRange() << Attr.getName() << 12 /* variable */;
3356f85e193739c953358c865005855253af4f68a497John McCall}
3357f85e193739c953358c865005855253af4f68a497John McCall
33581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
33591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
336087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
336187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3362768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << 12 /* variable */;
3363f85e193739c953358c865005855253af4f68a497John McCall    return;
3364f85e193739c953358c865005855253af4f68a497John McCall  }
3365f85e193739c953358c865005855253af4f68a497John McCall
336687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3367f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3368f85e193739c953358c865005855253af4f68a497John McCall
3369f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3370f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
337187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3372f85e193739c953358c865005855253af4f68a497John McCall      << type;
3373f85e193739c953358c865005855253af4f68a497John McCall    return;
3374f85e193739c953358c865005855253af4f68a497John McCall  }
3375f85e193739c953358c865005855253af4f68a497John McCall
3376f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3377f85e193739c953358c865005855253af4f68a497John McCall
3378f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3379f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3380f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3381f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3382f85e193739c953358c865005855253af4f68a497John McCall
3383f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3384f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3385f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3386f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3387f85e193739c953358c865005855253af4f68a497John McCall    break;
3388f85e193739c953358c865005855253af4f68a497John McCall
3389f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3390f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3391f85e193739c953358c865005855253af4f68a497John McCall    break;
3392f85e193739c953358c865005855253af4f68a497John McCall
3393f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3394f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
339587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3396f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3397f85e193739c953358c865005855253af4f68a497John McCall    break;
3398f85e193739c953358c865005855253af4f68a497John McCall  }
3399f85e193739c953358c865005855253af4f68a497John McCall
340087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3401768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3402f85e193739c953358c865005855253af4f68a497John McCall}
3403f85e193739c953358c865005855253af4f68a497John McCall
3404f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
3405f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
340611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
340711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
340811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
340911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
341011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
341111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
341211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
341311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
34141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
341562ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
341611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
34171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
341811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
34191731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
342011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
342111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
34225cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3423d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3424d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3425d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3426d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3427d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
34285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3429d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3430d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3431d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3432d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3433d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3434d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3435d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3436d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3437d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3438d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3439d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3440d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3441d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3442d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3443d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3444d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
34455f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3446f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3447f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3448f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3449f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3450d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3451d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3452d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3453d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3454d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3455d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3456d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3457d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3458d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3459d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3460d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
346111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
3462768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
346311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3464d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
346511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3466f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3467f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3468b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
34690744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
34700744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
34710744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
34721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
34731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
347460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
34751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
34761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
34771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
347860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
347960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
348060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
348160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3482e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
34831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
34841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3485803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
34861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break;
34871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
3488857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
34891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3490803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3491207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3492ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
34936e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
34944211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
34954211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3496bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3497bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3498803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
349960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
350060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
350160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
350260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
350360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
350460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
35051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
35061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3507bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
35081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3509b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
35101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
35111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
35121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3513bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
35141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
35151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
35161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
35171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
35181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
35191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
35203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
35211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
35223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
35231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
35241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
35251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
35261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
35277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
35281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
35297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
35301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
35311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
35321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
35331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
35341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3535dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3536dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3537dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
35381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
35391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
35401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
35411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
35421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
35431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3544b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3545b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
35461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3547f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
35481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3549f85e193739c953358c865005855253af4f68a497John McCall
3550dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3551dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3552dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3553fe98da0fa352462c02db037360788748f95466f7John McCall  case AttributeList::AT_ns_bridged:
3554fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
3555fe98da0fa352462c02db037360788748f95466f7John McCall
35568dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_audited_transfer:
35578dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_unknown_transfer:
35588dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
35598dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3560b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3561c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
35621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3563c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
35641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3565c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3566c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
356731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
356831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3569b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3570b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
35711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3572b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
35736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
35741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
35756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3576521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
35771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3578521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
35791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
35801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break;
35811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
35821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3583742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  case AttributeList::AT_arc_weakref_unavailable:
3584742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3585742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
35861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
3587f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  case AttributeList::AT_returns_twice:
3588f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
3589f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
35901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
35911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
35921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3593026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
35941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
35951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
35961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3597803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
35981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3599803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
36000db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
36011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
36020db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3603d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
36041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3605d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
36061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break;
36071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
36081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
36091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
36101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
36111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
36121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
36131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
36141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3615bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
361605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
361705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
36187255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
36191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
36207255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
362104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
362204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
362304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3624f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
362552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3626414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
36271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
362804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3629f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
36301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3631f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
363211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
36331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
363411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3635fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3636fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3637fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3638fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3639fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3640fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3641fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3642fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3643fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3644fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3645fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3646fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3647fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3648fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3649fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3650fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3651fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3652db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3656db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3657db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3658db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3659db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3660db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3661db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3662db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3663db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3664db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3666db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3667db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3668db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3670db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3671db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3672db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3673db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3674db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3675db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3676db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3677db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3678db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3679db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3680db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3681db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3682db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3683db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3684db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3685db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3686db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3687db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3688db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3689db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3690db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3691fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3692803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
369382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
369482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
369582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
36967d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
36977d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3698803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3699803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3700803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3701803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
370260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
370360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
370460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
370560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
37061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
37071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
370860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
370960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
371060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
371160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
371260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
371360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
371460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
371560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
371660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
37171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
371860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
371960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
37201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
372160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
372260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3723803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3724803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3725f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
372660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
372760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
372811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
37291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
373011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
373111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
373211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
373311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
373411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
373560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
373611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3737dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
373811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3739803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3740803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3741803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
3742e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
3743e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
3744e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
3745e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
3746e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
3747e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
3748e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
3749e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3750e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
3751e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
3752e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3753e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
3754e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
3755e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3756e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
3757e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
3758e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3759e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3760e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
3761e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
3762e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
3763e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
3764e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
3765e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
3766e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
3767e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
3768e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3769e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3770e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3771e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
3772900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
3773900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
37747b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3775e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3776e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3777900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
3778900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
3779900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
3780900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
3781900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
3782900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3783900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
3784900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
3785900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
3786900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
3787900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
3788900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
3789900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
3790900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3791900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
3792c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3793900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3794900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
3795900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
3796900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
3797900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
3798900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
3799900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
3800900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
3801900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
3802900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
3803900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
3804900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
38054278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
3806b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3807e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3808e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3809ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3810a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
381116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
381216573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3813b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3814b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3815c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3816b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3817e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3818e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3819e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3820e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3821e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3822e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
38237b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3824c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3825c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3826c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3827c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3828900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
3829cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3830cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3831cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3832c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3833c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3834c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3835c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3836c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3837c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3838c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3839c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3840cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3841e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3842e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3843e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
38440744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
38450744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
38460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
384760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
384860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3849d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3850d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
385131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
385231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
385331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
385431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
385531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
385631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
385731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
385831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
385931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
386031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
386131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
386231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3863d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3864e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3865e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3866e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3867e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
38680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
38697f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
387060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3871bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
38720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
38730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
38740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
38750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
38760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
38770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
387860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3879bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
38800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
38810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
388260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
38830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
388454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3885f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3886f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3887f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3888f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3889f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3890a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
3891a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
3892a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
3893f85e193739c953358c865005855253af4f68a497John McCall    return false;
3894f85e193739c953358c865005855253af4f68a497John McCall
3895f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3896f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3897f85e193739c953358c865005855253af4f68a497John McCall}
3898f85e193739c953358c865005855253af4f68a497John McCall
3899f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
3900f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3901f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
3902f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
3903f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3904f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
3905f85e193739c953358c865005855253af4f68a497John McCall    return;
3906f85e193739c953358c865005855253af4f68a497John McCall  }
3907175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian  if (S.getLangOptions().ObjCAutoRefCount)
3908175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
3909175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // FIXME. we may want to supress diagnostics for all
3910175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // kind of forbidden type messages on unavailable functions.
3911175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
3912175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag.getForbiddenTypeDiagnostic() ==
3913175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
3914175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
3915175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
3916175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
3917175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
3918f85e193739c953358c865005855253af4f68a497John McCall
3919f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3920f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3921f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
3922f85e193739c953358c865005855253af4f68a497John McCall}
3923f85e193739c953358c865005855253af4f68a497John McCall
3924eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3925eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3926eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3927eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3928eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3929eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3930eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3931eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3932eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3933eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3934eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3935eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3936eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3937eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3938eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3939eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3940eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3941eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3942eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3943eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3944eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
394554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
394654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3947eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3948eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
3949eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
395054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3951eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
3952eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
3953eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
3954eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
395554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3956eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
3957eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
395854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3959eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
3960eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
3961eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
396258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
39632f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
39642f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
3965a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis  if (decl && !decl->isInvalidDecl()) {
3966eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
3967eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
39682f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
39692f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
39702f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
39712f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
39722f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
3973eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3974eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
3975eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
39762f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
39772f514480c448708ec382a684cf5e035d3a827ec8John McCall
3978eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
39792f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
3980eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
39812f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
39822f514480c448708ec382a684cf5e035d3a827ec8John McCall
39832f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
3984eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
39852f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
3986f85e193739c953358c865005855253af4f68a497John McCall
3987f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
3988f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
3989f85e193739c953358c865005855253af4f68a497John McCall        break;
399054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
399154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
399254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
399354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
399458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
3995eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
399629233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
399758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
3998eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
39992f514480c448708ec382a684cf5e035d3a827ec8John McCall}
40002f514480c448708ec382a684cf5e035d3a827ec8John McCall
40012f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
40022f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
40030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
40042f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
40052f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
40062f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
40072f514480c448708ec382a684cf5e035d3a827ec8John McCall}
40082f514480c448708ec382a684cf5e035d3a827ec8John McCall
40099c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
40102f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
40112f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
40122f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
40132f514480c448708ec382a684cf5e035d3a827ec8John McCall
40142f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4015ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
4016c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
4017ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
4018ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
4019c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
4020c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
4021ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
402254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
402354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
40245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
40258e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
402689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
402754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4028eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
4029eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
403054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
403154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
403254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
403354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
40343a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
403554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4036ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
4037c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
4038c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
40398e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
4040743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
40418e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
404289ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
40438e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
404489ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
404589ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
40468e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
404754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4048