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"
17bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins#include "clang/AST/CXXInheritance.h"
18384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
19b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski#include "clang/AST/DeclTemplate.h"
20acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
21acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
22f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h"
23fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2419510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
26fe98da0fa352462c02db037360788748f95466f7John McCall#include "clang/Sema/Lookup.h"
27797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
299c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of
32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
33b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskienum AttributeDeclKind {
34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunction,
35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedUnion,
36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableOrFunction,
37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionOrMethod,
38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameter,
39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrBlock,
40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrParameter,
41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClass,
42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariable,
43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedMethod,
44db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  ExpectedVariableFunctionOrLabel,
45f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor  ExpectedFieldOrGlobalVar,
465e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  ExpectedStruct,
475e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  ExpectedTLSVar
48883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall};
49883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall
50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
52e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
53e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
5487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D,
55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
5787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
6187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
65bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
68755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
696217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
70d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
71183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
77d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
78a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
7987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) {
8087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return getFunctionType(D, false) != NULL;
81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
82a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
83a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
84d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
85d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
8687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) {
874ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky  return isFunction(D) || isa<ObjCMethodDecl>(D);
88d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
893568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
9387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
9487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isFunctionOrMethod(D))
95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
9787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
10187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<BlockDecl>(D);
102620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
103620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
104711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
105711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
10687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) {
107f85e193739c953358c865005855253af4f68a497John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
10887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
10987c44604325578b8de07d768391c1c9432404f5aChandler Carruth         isa<ObjCPropertyDecl>(D);
110711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
112d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
113d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
114620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
11587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) {
11687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
11772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
118620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
11987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
121d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1233568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
125d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
126d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
12787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) {
12887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
12972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
13087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
131d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
13287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_size();
1333568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1343568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
13687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
13772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
13887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
139d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
1423568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1433568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
14487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) {
14587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
1465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
14787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->getResultType();
1485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
15087c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) {
15187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D)) {
15272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
15487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
155db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
156d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
15787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    return cast<ObjCMethodDecl>(D)->isVariadic();
1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1603568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
16187c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) {
16287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
16507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
16607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
168183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
169b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
171bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
172506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
173506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
175bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
176506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
183085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1846217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
187085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1886217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
189085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
191bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
192085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
193465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
197085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
198085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
199b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May
200b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth                                  unsigned int Num) {
2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (Attr.getNumArgs() != Num) {
2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    return false;
2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  }
2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  return true;
2091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth}
2101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
211db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
212b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May
213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
215b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                  unsigned int Num) {
216b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (Attr.getNumArgs() < Num) {
217db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return false;
219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  return true;
222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
223db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
2240d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko/// \brief Check if IdxExpr is a valid argument index for a function or
2250d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko/// instance method D.  May output an error.
2260d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko///
2270d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko/// \returns true if IdxExpr is a valid index.
2280d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenkostatic bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D,
2290d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                               StringRef AttrName,
2300d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                               SourceLocation AttrLoc,
2310d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                               unsigned AttrArgNum,
2320d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                               const Expr *IdxExpr,
2330d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                               uint64_t &Idx)
2340d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko{
2350d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  assert(isFunctionOrMethod(D) && hasFunctionProto(D));
2360d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
2370d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  // In C++ the implicit 'this' function parameter also counts.
2380d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  // Parameters are counted from one.
2390d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  const bool HasImplicitThisParam = isInstanceMethod(D);
2400d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  const unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
2410d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  const unsigned FirstIdx = 1;
2420d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
2430d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  llvm::APSInt IdxInt;
2440d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2450d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko      !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) {
2460d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    S.Diag(AttrLoc, diag::err_attribute_argument_n_not_int)
2470d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko      << AttrName << AttrArgNum << IdxExpr->getSourceRange();
2480d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    return false;
2490d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  }
2500d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
2510d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  Idx = IdxInt.getLimitedValue();
2520d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  if (Idx < FirstIdx || (!isFunctionOrMethodVariadic(D) && Idx > NumArgs)) {
2530d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    S.Diag(AttrLoc, diag::err_attribute_argument_out_of_bounds)
2540d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko      << AttrName << AttrArgNum << IdxExpr->getSourceRange();
2550d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    return false;
2560d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  }
2570d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  Idx--; // Convert to zero-based.
2580d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  if (HasImplicitThisParam) {
2590d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    if (Idx == 0) {
2600d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko      S.Diag(AttrLoc,
2610d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko             diag::err_attribute_invalid_implicit_this_argument)
2620d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko        << AttrName << IdxExpr->getSourceRange();
2630d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko      return false;
2640d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    }
2650d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    --Idx;
2660d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  }
2670d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
2680d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  return true;
2690d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko}
2700d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
271db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski///
272fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var
273fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable
274fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
27539997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) {
276fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (isa<FieldDecl>(D))
277fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return true;
27839997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const VarDecl *vd = dyn_cast<VarDecl>(D))
279fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
280fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
281fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
282fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
283fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
284b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool.
285b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) {
286b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = Exp->getType();
287b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return QT->isBooleanType() || QT->isIntegerType();
288b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
289b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
290aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
291aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// Check to see if the type is a smart pointer of some kind.  We assume
292aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// it's a smart pointer if it defines both operator-> and operator*.
29360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchinsstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
29460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
29560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
29660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (Res1.first == Res1.second)
29760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return false;
29860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
29960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
30060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
30160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (Res2.first == Res2.second)
30260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return false;
30360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
30460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  return true;
305aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins}
306aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
307fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type.
308fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message.
309fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise
310ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
311ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                       const AttributeList &Attr) {
31239997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
313fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
31439997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer    if (QT->isAnyPointerType())
315fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
316aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
31760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    if (const RecordType *RT = QT->getAs<RecordType>()) {
31860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // If it's an incomplete type, it could be a smart pointer; skip it.
31960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // (We don't want to force template instantiation if we can avoid it,
32060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // since that would alter the order in which templates are instantiated.)
32160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      if (RT->isIncompleteType())
32260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins        return true;
32360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
32460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      if (threadSafetyCheckIsSmartPointer(S, RT))
32560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins        return true;
32660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    }
327aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
328ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
329fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
330fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
331fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
332fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
333fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
334fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
335fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
336fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
337b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points
338b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit.
3397d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) {
3407d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const RecordType *RT = QT->getAs<RecordType>())
341b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return RT;
3427d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
3437d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  // Now check if we point to record type.
3447d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const PointerType *PT = QT->getAs<PointerType>())
3457d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer    return PT->getPointeeType()->getAs<RecordType>();
3467d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
3477d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  return 0;
348b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
349b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
350bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
351fad5de9d674521017460f8445e2f81e2a1086290Jordy Rosestatic bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
352fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                             CXXBasePath &Path, void *Unused) {
353bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  const RecordType *RT = Specifier->getType()->getAs<RecordType>();
354bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (RT->getDecl()->getAttr<LockableAttr>())
355bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    return true;
356bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  return false;
357bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins}
358bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
359bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
3603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType
361ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// resolves to a lockable object.
36283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchinsstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
36383cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins                                   QualType Ty) {
36483cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  const RecordType *RT = getRecordType(Ty);
36508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
36683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  // Warn if could not get record type for this argument.
367d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT) {
368ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
36983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      << Attr.getName() << Ty.getAsString();
37083cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
3713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
37260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
37308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  // Don't check for lockable if the class hasn't been defined yet.
374634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  if (RT->isIncompleteType())
37583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
37660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
37760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  // Allow smart pointers to be used as lockable objects.
37860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  // FIXME -- Check the type that the smart pointer points to.
37960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (threadSafetyCheckIsSmartPointer(S, RT))
38060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return;
38160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
382bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  // Check if the type is lockable.
383bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  RecordDecl *RD = RT->getDecl();
384bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (RD->getAttr<LockableAttr>())
38583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
386bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
387bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  // Else check if any base classes are lockable.
388bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
389bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    CXXBasePaths BPaths(false, false);
390bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths))
391bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins      return;
3923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
393bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
394bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
395bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    << Attr.getName() << Ty.getAsString();
3963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
398b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
399ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// from Sidx, resolve to a lockable object.
4003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with.
4013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function
4023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list.
403ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
4043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         const AttributeList &Attr,
4053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         SmallVectorImpl<Expr*> &Args,
406b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
407b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
4083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
409b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
4103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
411ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    if (ArgExp->isTypeDependent()) {
412ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // FIXME -- need to check this again on template instantiation
413ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      Args.push_back(ArgExp);
414ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      continue;
415ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    }
416b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
41779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
4180b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      if (StrLit->getLength() == 0 ||
4190b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins          StrLit->getString() == StringRef("*")) {
4204e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins        // Pass empty strings to the analyzer without warnings.
4210b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins        // Treat "*" as the universal lock.
4224e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins        Args.push_back(ArgExp);
42379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        continue;
4244e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins      }
42579747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
426ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // We allow constant strings to be used as a placeholder for expressions
427ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // that are not valid C++ syntax, but warn that they are ignored.
428ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
429ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins        Attr.getName();
4304e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins      Args.push_back(ArgExp);
431ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      continue;
432ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    }
433ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins
4343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
435b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
43679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // A pointer to member expression of the form  &MyClass::mu is treated
43779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // specially -- we need to look at the type of the member.
43879747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
43979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (UOp->getOpcode() == UO_AddrOf)
44079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
44179747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins          if (DRE->getDecl()->isCXXInstanceMember())
44279747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins            ArgTy = DRE->getDecl()->getType();
44379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
4443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
4453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
446b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
4483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
4493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
450b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
451b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
452b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
453b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
4543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
4553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
4563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
457b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
458b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
459ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins          continue;
460b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
4613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
462b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
463b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
464b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
46583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    checkForLockableRecord(S, D, Attr, ArgTy);
466b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
468b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
469b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
470b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
471e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
472e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
473e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
474e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
4773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
4783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4790aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchinsenum ThreadAttributeDeclKind {
4800aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins  ThreadExpectedFieldOrGlobalVar,
4810aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins  ThreadExpectedFunctionOrMethod,
4820aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins  ThreadExpectedClassOrStruct
4830aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins};
4840aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins
48508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkGuardedVarAttrCommon(Sema &S, Decl *D,
486dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                      const AttributeList &Attr) {
487fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
488fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
489fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
490dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
491fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
492fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
493fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
4940aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
4950aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
496dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
497fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
498fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
499dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
500dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
501dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
502dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Hanstatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) {
503dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkGuardedVarAttrCommon(S, D, Attr))
504fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
505fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
506dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
507fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
508fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
50908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handlePtGuardedVarAttr(Sema &S, Decl *D,
510dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                           const AttributeList &Attr) {
511dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkGuardedVarAttrCommon(S, D, Attr))
512dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
514dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!threadSafetyCheckIsPointer(S, D, Attr))
515db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
516db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
517dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
518fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
519fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
52008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkGuardedByAttrCommon(Sema &S, Decl *D,
52108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                     const AttributeList &Attr,
522dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                     Expr* &Arg) {
523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
525b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
526dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
5273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
528db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
529db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
5300aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
5310aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
532dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
533db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
534db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
535ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  SmallVector<Expr*, 1> Args;
536ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // check that all arguments are lockable objects
537ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
538ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  unsigned Size = Args.size();
539ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size != 1)
540dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
541db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
542dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Arg = Args[0];
543b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
544dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
545dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
546dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
547dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Hanstatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) {
548dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr *Arg = 0;
549dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
550ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
551b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
552dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
554db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
55508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handlePtGuardedByAttr(Sema &S, Decl *D,
556dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                  const AttributeList &Attr) {
557dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr *Arg = 0;
558dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
559dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
560dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
561dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!threadSafetyCheckIsPointer(S, D, Attr))
562dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
563dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
564dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
565dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                               S.Context, Arg));
566dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
56808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkLockableAttrCommon(Sema &S, Decl *D,
569dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                    const AttributeList &Attr) {
570fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
571fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
572fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
573dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
574fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
5751748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
576fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
5770aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
5780aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedClassOrStruct;
579dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
580fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
581fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
582dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
583dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
584dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
585dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Hanstatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
586dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLockableAttrCommon(S, D, Attr))
587dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
588dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
589dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
590dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
591dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
59208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleScopedLockableAttr(Sema &S, Decl *D,
593dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                             const AttributeList &Attr) {
594dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLockableAttrCommon(S, D, Attr))
595dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
596dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
597dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
598fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
599fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
600fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
601fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
602fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
603fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
604fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
605fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
606fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
607b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
6080aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
6090aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
610fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
611fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
612fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
613768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
614fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
615fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
616fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
61771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D,
618ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                      const AttributeList &Attr) {
61971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  assert(!Attr.isInvalid());
62071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
62171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!checkAttributeNumArgs(S, Attr, 0))
62271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
62371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
62471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
62571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
62671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany      << Attr.getName() << ExpectedFunctionOrMethod;
62771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
62871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  }
62971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
63071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
631f50b6fe092091a700cee7a708d509ae7c49709f6Nick Lewycky                                                           S.Context));
63271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany}
63371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
63408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
63508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                        const AttributeList &Attr,
636dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                        SmallVector<Expr*, 1> &Args) {
637db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
638db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
639b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
640dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
641db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
643b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
644b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
6450aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
6460aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
647dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
648db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
650ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that this attribute only applies to lockable types.
651b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
652b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
653b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
654b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
655ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
656dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han        << Attr.getName();
657dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han      return false;
658b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
659b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
660b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
661ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that all arguments are lockable objects.
662ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
663dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (Args.size() == 0)
664dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
66508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
666dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
667dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
668dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
66908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleAcquiredAfterAttr(Sema &S, Decl *D,
670dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                    const AttributeList &Attr) {
6713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
672dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
673b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
674b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
675ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
676dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
6774ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky                                                 StartArg, Args.size()));
678dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
6793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
68008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleAcquiredBeforeAttr(Sema &S, Decl *D,
681dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                     const AttributeList &Attr) {
682dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  SmallVector<Expr*, 1> Args;
683dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
684dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
685dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
686dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr **StartArg = &Args[0];
687dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
6884ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky                                                  StartArg, Args.size()));
689db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
690db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
69108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkLockFunAttrCommon(Sema &S, Decl *D,
69208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                   const AttributeList &Attr,
693dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                   SmallVector<Expr*, 1> &Args) {
694db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
695db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
696db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
697db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
698b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
699b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
7000aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
7010aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
702dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
703db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
704db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
705b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
706ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
707dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
708dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
709dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
710dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
71108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleSharedLockFunctionAttr(Sema &S, Decl *D,
712dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                         const AttributeList &Attr) {
7133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
714dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLockFunAttrCommon(S, D, Attr, Args))
715b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
716b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
7173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
7183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
719dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
72008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                      S.Context,
721dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                      StartArg, Size));
722dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
7233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
72408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
725dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                            const AttributeList &Attr) {
726dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  SmallVector<Expr*, 1> Args;
727dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLockFunAttrCommon(S, D, Attr, Args))
728dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
729dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
730dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  unsigned Size = Args.size();
731dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr **StartArg = Size == 0 ? 0 : &Args[0];
732dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
73308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                         S.Context,
734dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                         StartArg, Size));
735db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
736db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
73708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
73808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                      const AttributeList &Attr,
739dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                      SmallVector<Expr*, 2> &Args) {
740db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
741db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
742b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
743dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
744b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
745b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
7460aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
7470aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
748dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
749db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
750db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
751b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
752b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
753dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han      << Attr.getName();
754dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
755b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
756b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
757b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
758ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
759dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
760dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
761dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
762dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
76308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
764dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                            const AttributeList &Attr) {
765dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  SmallVector<Expr*, 2> Args;
766dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
767b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
768b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
7693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
7703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
771dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
77208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                         S.Context,
77308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                         Attr.getArg(0),
774dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                         StartArg, Size));
775dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
7763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
77708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
778dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                               const AttributeList &Attr) {
779dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  SmallVector<Expr*, 2> Args;
780dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
781dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
782dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
783dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  unsigned Size = Args.size();
784dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr **StartArg = Size == 0 ? 0 : &Args[0];
785dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
78608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                            S.Context,
78708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                            Attr.getArg(0),
788dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                            StartArg, Size));
789db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
790db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
79108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkLocksRequiredCommon(Sema &S, Decl *D,
79208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                     const AttributeList &Attr,
793dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                     SmallVector<Expr*, 1> &Args) {
794db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
795db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
796b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
797dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
798db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
799b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
8000aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
8010aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
802dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
803db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
804db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
805b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
806ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
807dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (Args.size() == 0)
808dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return false;
80908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
810dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  return true;
811dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
812dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
81308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D,
814dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                             const AttributeList &Attr) {
8153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
816dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLocksRequiredCommon(S, D, Attr, Args))
817b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
818b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
819ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
820dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
82108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                          S.Context,
82208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                          StartArg,
823dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                          Args.size()));
824dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han}
8253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
82608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleSharedLocksRequiredAttr(Sema &S, Decl *D,
827dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                          const AttributeList &Attr) {
828dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  SmallVector<Expr*, 1> Args;
829dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  if (!checkLocksRequiredCommon(S, D, Attr, Args))
830dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    return;
831dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han
832dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  Expr **StartArg = &Args[0];
833dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han  D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
83408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                       S.Context,
83508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao                                                       StartArg,
836dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han                                                       Args.size()));
837db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
838db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
839db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
840b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
841db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
842db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
843db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
844db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
845b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
8460aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
8470aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
848db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
849db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
850db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
851b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
8523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
853ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
8543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
8553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
8563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
857768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
8583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
859db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
860db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
861db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
862b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
863db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
864db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
865b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
866db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
8673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
868db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
869b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
8700aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
8710aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
872db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
873db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
874db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
8753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
876b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
877b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
8783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
879f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  SmallVector<Expr*, 1> Args;
880f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
881f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  unsigned Size = Args.size();
882f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  if (Size == 0)
883f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins    return;
8843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
885f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context,
886f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins                                                Args[0]));
887db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
888db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
889db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
890b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
891db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
892db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
893b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
894db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
895db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
896b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
8970aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
8980aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins      << Attr.getName() << ThreadExpectedFunctionOrMethod;
899db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
900db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
901db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
902b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
9033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
904ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
9053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
906ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
907ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
908ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
9093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
910768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
9113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
912db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
913db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
914db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
9151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
9161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
91787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
918545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
919803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
920545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
9216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
922bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
9236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
9249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
9259cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
9269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
9279cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
9289cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
929f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
930e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    SourceLocation TemplateKWLoc;
931f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
932f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
93308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
934e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id,
935e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                          false, false);
9364ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
9374ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
93808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
9394ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
9409cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
9419cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
9421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
9439cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
9441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
9457a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
9466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9479cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
9489cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
9499cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
9509ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
9519cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
952ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
953a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
954bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
9559cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
9569cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
9576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
9616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
9621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
9636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
964bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
96587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
966768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
96787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
9686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
9696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
9706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
971803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
972fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
97308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
9746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
975768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
9766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
9773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
9786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
98187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
982768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
983c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
984c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
985c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
986c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
9871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
98896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
9891731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
99096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
991bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
99263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
99387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
99463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
995768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
99663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
99763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
99863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
9994ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
100063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
100163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
10022f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
10032f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // The IBOutlet/IBOutletCollection attributes only apply to instance
10042f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // variables or properties of Objective-C classes.  The outlet must also
10052f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // have an object reference type.
10062f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
10072f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
10080bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
10092f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << VD->getType() << 0;
10102f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
10112f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
10122f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
10132f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
10142f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
1015f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
10162f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << PD->getType() << 1;
10172f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
10182f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
10192f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
10202f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else {
10212f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
10222f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    return false;
10232f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
1024f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
10252f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  return true;
10262f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek}
10272f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
10281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
102963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
10301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
103163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
103208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
10332f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
103463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
103563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
10362f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
103796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
103896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
10391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
10401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
1041857e918a8a40deb128840308a318bf623d68295fTed Kremenek
1042857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
1043a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
1044857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1045857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
1046857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
1047857e918a8a40deb128840308a318bf623d68295fTed Kremenek
10482f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
1049857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
10502f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
1051a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
1052a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
1053f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian    II = &S.Context.Idents.get("NSObject");
105408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
105508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
105687c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
1057a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
1058a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
1059a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
1060a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
1061b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
1062a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
1063a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
1064a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
1065a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
1066f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
1067a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
1068a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
1069a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
1070f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
1071f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
1072857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
1073857e918a8a40deb128840308a318bf623d68295fTed Kremenek
1074d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
107568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
107668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
107768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
107868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
107968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
108068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
108168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
108268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
108368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
108468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
108568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
108668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
108768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
108868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
1089587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopesstatic void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1090174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes  if (!isFunctionOrMethod(D)) {
1091174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1092174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes    << "alloc_size" << ExpectedFunctionOrMethod;
1093174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes    return;
1094174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes  }
1095174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes
1096587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
1097587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    return;
1098587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1099587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  // In C++ the implicit 'this' function parameter also counts, and they are
1100587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  // counted from one.
1101587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  bool HasImplicitThisParam = isInstanceMethod(D);
1102587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1103587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1104587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  SmallVector<unsigned, 8> SizeArgs;
1105587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1106587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  for (AttributeList::arg_iterator I = Attr.arg_begin(),
1107587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes       E = Attr.arg_end(); I!=E; ++I) {
1108587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    // The argument must be an integer constant expression.
1109587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    Expr *Ex = *I;
1110587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    llvm::APSInt ArgNum;
1111587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
1112587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
1113587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1114587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      << "alloc_size" << Ex->getSourceRange();
1115587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      return;
1116587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
1117587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1118587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    uint64_t x = ArgNum.getZExtValue();
1119587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1120587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (x < 1 || x > NumArgs) {
1121587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1122587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      << "alloc_size" << I.getArgNum() << Ex->getSourceRange();
1123587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      return;
1124587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
1125587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1126587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    --x;
1127587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (HasImplicitThisParam) {
1128587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      if (x == 0) {
1129587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        S.Diag(Attr.getLoc(),
1130587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes               diag::err_attribute_invalid_implicit_this_argument)
1131587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        << "alloc_size" << Ex->getSourceRange();
1132587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        return;
1133587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      }
1134587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      --x;
1135587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
1136587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1137587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    // check if the function argument is of an integer type
1138587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
1139587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (!T->isIntegerType()) {
1140587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1141587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      << "alloc_size" << Ex->getSourceRange();
1142587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      return;
1143587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
1144587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1145587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    SizeArgs.push_back(x);
1146587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  }
1147587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
1148587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  // check if the function returns a pointer
1149587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  if (!getFunctionType(D)->getResultType()->isAnyPointerType()) {
1150587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
1151587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    << "alloc_size" << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange();
1152587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  }
1153587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
115496c67d1c2aff532729c9edb297617094d1e77cc1Nuno Lopes  D->addAttr(::new (S.Context) AllocSizeAttr(Attr.getRange(), S.Context,
115596c67d1c2aff532729c9edb297617094d1e77cc1Nuno Lopes                                             SizeArgs.data(), SizeArgs.size()));
1156587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes}
1157587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
11581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1159bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
1160bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
116187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
1162fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1163883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1164eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
1165eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
1166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
116707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
116807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
116987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
117087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1171eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
1172eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
11735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
1174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1175eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
1176eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
1177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1178bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1179eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
11807a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
1181eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
1182ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
1183ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
1184fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1185fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
1186eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
1187eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
1188bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1189eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1191eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
1192fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
119330bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
1194eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
1195eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
1196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1197465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
119807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
119907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
120007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
120107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
120207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
120307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
120407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
120507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
120607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
1207eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
1208eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
120987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
1210d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
121108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1212dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1213eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
1214c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
1215fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
12167fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
1217eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
1218bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1219eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
1220eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
1221bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
1223bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
12247fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
122587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
122687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
1227d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
1228dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
1229d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
123046bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
1231bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1232ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
123360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
123460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
123560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
123660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
123760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
12387fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
123960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
1240eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
12417fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
12427fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
12437fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
1244dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1245768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
1246cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
1247eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
1248eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
12491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
1250dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
1251dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
1252dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
1253dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
1254dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
1255dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
12562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
12572a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
1258dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1259dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
1260dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
1261dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
1262dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1263dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1264dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
1265cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
12662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
12672a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
1268cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
1269dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
1270dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1271dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1272dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
12732a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
12742a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
1275cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
1276dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
1277dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1278dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1279dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
12802a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
12812a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
1282cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
1283dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
1284dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
1285dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
1286dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1287dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
12882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
12892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
12902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
12912a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
1292dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1293dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
129487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
1295883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1296883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
1297dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1298dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1299dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
130007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
130107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
130287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
130387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1304dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
13055f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
1306dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1307dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
1308dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
1309dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
1310dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
13115f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
1312dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
13132a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
13142a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1315dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
13167a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1317dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1318dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1319dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1320dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1321dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1322dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1323dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1324dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1325dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1326dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1327dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1328dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1329dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1330dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1331dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1332dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
133307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
133407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
133507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
133607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
133707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
133807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
133907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
134007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
134107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1342dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1343cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1344cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1345dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
134687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1347dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1348dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1349dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1350cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1351dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1352dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1353dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1354dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1355dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1356dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1357cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1358dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1359dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
13607a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1361dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1362dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1363dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1364dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1365dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1366dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1367dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1368dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1369dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1370dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1371dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1372dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1373dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1374dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1375cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
137687c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
137787c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1378cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1379cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1380cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1381cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1382cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1383cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1384cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1385dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1386dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1387dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1388dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1389dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1390dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1391dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1392dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1393dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1394dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1395cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1396cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1397cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1398cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1399dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1400cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
140187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1402cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1403dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1404dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1405332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1406332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1407332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1408332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1409332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1410332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1411332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1412332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1413332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1414332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1415332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1416332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1417332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1418332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1419332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1420332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1421332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
142211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
142311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
14241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
142511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
142611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
142711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
142811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
142911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
143011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
143187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1432332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1433883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1434332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1435332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1436332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
143787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1438332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
143911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
144011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
144111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
144211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
144311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
144411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
144511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
144611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
144711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
144811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
144987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
14507a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
14517a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1452332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
14537a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
145411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
145511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
145611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
145711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
145811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
145911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
146011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
146111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
146211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
146311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
146411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
146511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
146611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
146711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
146811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
146911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
147011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
147111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
147211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
147311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1474332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1475332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
147611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
147711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
147811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
147911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
148011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
148111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
148211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
148311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
14847a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
148511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
148611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
148711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
14885cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
148911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
149011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
149111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
149211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
149311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
149411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1495768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1496f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
149711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
149811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1499768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
150011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
150111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
15021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1504545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
15053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
15066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1508bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15097a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
15106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
15116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1512bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15135cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1514fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
15153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
15166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1518bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1519bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1520f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1521f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1522f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1523f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
15246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1525bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1526768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1527f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
15286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1530ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramerstatic void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1531ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  // Check the attribute arguments.
1532ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!checkAttributeNumArgs(S, Attr, 0))
1533ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1534ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1535ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!isa<FunctionDecl>(D)) {
1536ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1537ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << ExpectedFunction;
1538ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1539ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1540ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1541ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (D->hasAttr<HotAttr>()) {
1542ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1543ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << "hot";
1544ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1545ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1546ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1547ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context));
1548ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer}
1549ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1550ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramerstatic void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1551ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  // Check the attribute arguments.
1552ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!checkAttributeNumArgs(S, Attr, 0))
1553ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1554ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1555ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!isa<FunctionDecl>(D)) {
1556ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1557ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << ExpectedFunction;
1558ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1559ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1560ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1561ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (D->hasAttr<ColdAttr>()) {
1562ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1563ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << "cold";
1564ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1565ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1566ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1567ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context));
1568ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer}
1569ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
15701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1571dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
15721731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1573dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1574dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
157587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1576dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1577883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1578dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1579dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1580dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1581768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1582dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1583dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
15841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
15851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1586dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1587831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
15883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1589af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1590af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
15915bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
159287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
15935bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1594883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15955bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
15965bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1597bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1598768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1599af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1600af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
16015e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborgstatic void handleTLSModelAttr(Sema &S, Decl *D,
16025e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg                               const AttributeList &Attr) {
16035e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  // Check the attribute arguments.
16045e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  if (Attr.getNumArgs() != 1) {
16055e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
16065e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    return;
16075e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  }
16085e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
16095e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  Expr *Arg = Attr.getArg(0);
16105e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  Arg = Arg->IgnoreParenCasts();
16115e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
16125e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
16135e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  // Check that it is a string.
16145e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  if (!Str) {
16155e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    S.Diag(Attr.getLoc(), diag::err_attribute_not_string) << "tls_model";
16165e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    return;
16175e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  }
16185e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
16195e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->isThreadSpecified()) {
16205e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
16215e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg      << Attr.getName() << ExpectedTLSVar;
16225e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    return;
16235e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  }
16245e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
16255e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  // Check that the value.
16265e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  StringRef Model = Str->getString();
16275e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  if (Model != "global-dynamic" && Model != "local-dynamic"
16285e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg      && Model != "initial-exec" && Model != "local-exec") {
16295e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    S.Diag(Attr.getLoc(), diag::err_attr_tlsmodel_arg);
16305e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg    return;
16315e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  }
16325e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
16335e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  D->addAttr(::new (S.Context) TLSModelAttr(Attr.getRange(), S.Context,
16345e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg                                            Model));
16355e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg}
16365e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg
16371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1638dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1639831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
164076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
164176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
164276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
16431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
164487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
16451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
16462cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1647768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
16482cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
16492cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1650fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1651fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
16522cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
165376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
165476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
16551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
165634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
16571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
165834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
165934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1660768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
166134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
166234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
16631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
166456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
166587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1666768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1667722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1668722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1669883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1670a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1671a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
16721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
167356aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
167487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1675768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1676722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1677722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1678883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1679a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1680a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
16811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
168287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1683711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1684711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1685711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
168687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1687711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1688883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1689711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1690711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1691711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1692768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1693711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1694711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1695711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1696831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1697711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1698711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1699711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1700711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1701711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1702711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1703b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1704b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
17051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
17061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
170708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1708b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1709b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
171008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
17111731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
17121731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
171308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
171487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
171587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
17163ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
17173ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1718e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1719e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1720b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1721883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1722b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
172319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
17246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
172508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1726768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
17276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
172935cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
17301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
173135cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
173235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
173308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
173408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  According to the PPU ABI specifications, a class with a single member of
1735f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1736f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1737f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1738f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
173908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
174035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
174108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
174235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
174335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
174435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
174535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
174608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
174735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
174835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
174935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
175035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
175135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
175235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
175335cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
175487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
175535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1756883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
175735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
175835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
175935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
176087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
176135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
176235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
176335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
176435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
176587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
176601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
176701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
176801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
176901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
177001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
177101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
177201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
177301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
177401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
177501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
177601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
177701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1778f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1779f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
178001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
178101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
178201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
178301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
178401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
178501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
178601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1787768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
178835cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
178935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
17901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
179187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1792bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1793883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1794bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1795bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1796bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1797bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1798bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
17991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
180073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1801831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
18023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
180373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
180473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1805bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
180687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
1807568eae48a4e19c0359cdcd2a33b8ec9812e4abbcDaniel Jasper      !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) {
1808fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1809883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
181073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
181173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1812bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1813768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
181473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
181573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1816f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1817f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1818f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1819f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1820f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1821f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1822f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1823f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1824f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1825f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1826f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1827f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1828f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1829f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1830f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1831f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1832f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
18331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1834b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1835831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1836b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1837b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1838b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1839bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
184087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1841186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1842b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1843b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1844b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
184587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1846b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1847883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1848b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1849b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1850bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1851768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1852b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1853b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
18541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1856bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1857bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
18583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1859bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
18603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
18613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
18623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
18637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
18643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1865ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1866ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1867fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
18693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
18703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
18713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
18723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1873bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
187487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1875fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1876883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
18773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
18783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
18793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1880768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1881f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
18823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
18833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
18841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1886bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1887bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
18883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1889bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
18903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
18913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
18923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
18937a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
18943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1895ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1896ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1897fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
18993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
19003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
19013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
19023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1903bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
190487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1905fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1906883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
19073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
19083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
19093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1910768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1911f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
19123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
19133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1914bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramertemplate <typename AttrTy>
1915bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramerstatic void handleAttrWithMessage(Sema &S, Decl *D, const AttributeList &Attr,
1916bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer                                  const char *Name) {
1917951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1918951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1919bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1920c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1921c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1922bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer
1923bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer  // Handle the case where the attribute has a text message.
19245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1925951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1926951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1927c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1928951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1929bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer        << Name;
1930c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1931c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1932951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
19336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1934bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1935bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer  D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str));
1936bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1937bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
193808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1939742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1940742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1941742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1942742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1943742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1944742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
194508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1946742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1947768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1948742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1949742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
195008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleObjCRootClassAttr(Sema &S, Decl *D,
1951b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard                                    const AttributeList &Attr) {
1952b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (!isa<ObjCInterfaceDecl>(D)) {
1953b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1954b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1955b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
195608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1957b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  unsigned NumArgs = Attr.getNumArgs();
1958b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (NumArgs > 0) {
1959b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1960b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1961b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
196208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1963b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
1964b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard}
1965b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
196608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
1967e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                            const AttributeList &Attr) {
1968341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  if (!isa<ObjCInterfaceDecl>(D)) {
1969341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
1970341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    return;
1971341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  }
197208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
1973e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1974e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  if (NumArgs > 0) {
1975e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1976e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    return;
1977e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  }
197808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
197971207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
1980e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                 Attr.getRange(), S.Context));
1981e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian}
1982e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
1983fad5de9d674521017460f8445e2f81e2a1086290Jordy Rosestatic bool checkAvailabilityAttr(Sema &S, SourceRange Range,
1984fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  IdentifierInfo *Platform,
1985fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  VersionTuple Introduced,
1986fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  VersionTuple Deprecated,
1987fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  VersionTuple Obsoleted) {
19885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
19890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
19903b294360febd89e3383143af086efe2014571afaRafael Espindola  if (PlatformName.empty())
19910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
19920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1993c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
19940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
19953b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Introduced.empty() && !Deprecated.empty() &&
19963b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Introduced <= Deprecated)) {
19973b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
19983b294360febd89e3383143af086efe2014571afaRafael Espindola      << 1 << PlatformName << Deprecated.getAsString()
19993b294360febd89e3383143af086efe2014571afaRafael Espindola      << 0 << Introduced.getAsString();
20003b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
20010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
20020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
20033b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Introduced.empty() && !Obsoleted.empty() &&
20043b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Introduced <= Obsoleted)) {
20053b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
20063b294360febd89e3383143af086efe2014571afaRafael Espindola      << 2 << PlatformName << Obsoleted.getAsString()
20073b294360febd89e3383143af086efe2014571afaRafael Espindola      << 0 << Introduced.getAsString();
20083b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
20090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
20100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
20113b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Deprecated.empty() && !Obsoleted.empty() &&
20123b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Deprecated <= Obsoleted)) {
20133b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
20143b294360febd89e3383143af086efe2014571afaRafael Espindola      << 2 << PlatformName << Obsoleted.getAsString()
20153b294360febd89e3383143af086efe2014571afaRafael Espindola      << 1 << Deprecated.getAsString();
20163b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
20173b294360febd89e3383143af086efe2014571afaRafael Espindola  }
20183b294360febd89e3383143af086efe2014571afaRafael Espindola
20193b294360febd89e3383143af086efe2014571afaRafael Espindola  return false;
20203b294360febd89e3383143af086efe2014571afaRafael Espindola}
20213b294360febd89e3383143af086efe2014571afaRafael Espindola
2022599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaAvailabilityAttr *Sema::mergeAvailabilityAttr(Decl *D, SourceRange Range,
2023599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              IdentifierInfo *Platform,
2024599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              VersionTuple Introduced,
2025599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              VersionTuple Deprecated,
2026599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              VersionTuple Obsoleted,
2027599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              bool IsUnavailable,
2028599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              StringRef Message) {
202998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VersionTuple MergedIntroduced = Introduced;
203098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VersionTuple MergedDeprecated = Deprecated;
203198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VersionTuple MergedObsoleted = Obsoleted;
20323b294360febd89e3383143af086efe2014571afaRafael Espindola  bool FoundAny = false;
20333b294360febd89e3383143af086efe2014571afaRafael Espindola
203498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  if (D->hasAttrs()) {
203598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    AttrVec &Attrs = D->getAttrs();
203698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    for (unsigned i = 0, e = Attrs.size(); i != e;) {
203798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
203898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (!OldAA) {
203998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        ++i;
204098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
204198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
204298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
204398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      IdentifierInfo *OldPlatform = OldAA->getPlatform();
204498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (OldPlatform != Platform) {
204598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        ++i;
204698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
204798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
204898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
204998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      FoundAny = true;
205098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple OldIntroduced = OldAA->getIntroduced();
205198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple OldDeprecated = OldAA->getDeprecated();
205298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple OldObsoleted = OldAA->getObsoleted();
205398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      bool OldIsUnavailable = OldAA->getUnavailable();
205498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      StringRef OldMessage = OldAA->getMessage();
205598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
205698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if ((!OldIntroduced.empty() && !Introduced.empty() &&
205798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola           OldIntroduced != Introduced) ||
205898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (!OldDeprecated.empty() && !Deprecated.empty() &&
205998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola           OldDeprecated != Deprecated) ||
206098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (!OldObsoleted.empty() && !Obsoleted.empty() &&
206198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola           OldObsoleted != Obsoleted) ||
206298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (OldIsUnavailable != IsUnavailable) ||
206398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (OldMessage != Message)) {
206498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
206598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Diag(Range.getBegin(), diag::note_previous_attribute);
206698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Attrs.erase(Attrs.begin() + i);
206798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        --e;
206898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
206998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
207098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
207198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple MergedIntroduced2 = MergedIntroduced;
207298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple MergedDeprecated2 = MergedDeprecated;
207398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple MergedObsoleted2 = MergedObsoleted;
207498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
207598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (MergedIntroduced2.empty())
207698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        MergedIntroduced2 = OldIntroduced;
207798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (MergedDeprecated2.empty())
207898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        MergedDeprecated2 = OldDeprecated;
207998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (MergedObsoleted2.empty())
208098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        MergedObsoleted2 = OldObsoleted;
208198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
208298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
208398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola                                MergedIntroduced2, MergedDeprecated2,
208498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola                                MergedObsoleted2)) {
208598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Attrs.erase(Attrs.begin() + i);
208698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        --e;
208798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
208898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
208998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
209098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      MergedIntroduced = MergedIntroduced2;
209198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      MergedDeprecated = MergedDeprecated2;
209298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      MergedObsoleted = MergedObsoleted2;
209398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      ++i;
209498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    }
20950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
20960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
20973b294360febd89e3383143af086efe2014571afaRafael Espindola  if (FoundAny &&
20983b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedIntroduced == Introduced &&
20993b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedDeprecated == Deprecated &&
21003b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedObsoleted == Obsoleted)
2101599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return NULL;
21023b294360febd89e3383143af086efe2014571afaRafael Espindola
210398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
21043b294360febd89e3383143af086efe2014571afaRafael Espindola                             MergedDeprecated, MergedObsoleted)) {
2105599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return ::new (Context) AvailabilityAttr(Range, Context, Platform,
2106599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                            Introduced, Deprecated,
2107599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                            Obsoleted, IsUnavailable, Message);
21080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
2109599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return NULL;
21103b294360febd89e3383143af086efe2014571afaRafael Espindola}
21110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
21123b294360febd89e3383143af086efe2014571afaRafael Espindolastatic void handleAvailabilityAttr(Sema &S, Decl *D,
21133b294360febd89e3383143af086efe2014571afaRafael Espindola                                   const AttributeList &Attr) {
21143b294360febd89e3383143af086efe2014571afaRafael Espindola  IdentifierInfo *Platform = Attr.getParameterName();
21153b294360febd89e3383143af086efe2014571afaRafael Espindola  SourceLocation PlatformLoc = Attr.getParameterLoc();
21163b294360febd89e3383143af086efe2014571afaRafael Espindola
21173b294360febd89e3383143af086efe2014571afaRafael Espindola  if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty())
21183b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
21193b294360febd89e3383143af086efe2014571afaRafael Espindola      << Platform;
21200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
21213b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
21223b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
21233b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
21243b294360febd89e3383143af086efe2014571afaRafael Espindola  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
2125006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  StringRef Str;
212608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  const StringLiteral *SE =
2127006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
2128006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  if (SE)
2129006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    Str = SE->getString();
21303b294360febd89e3383143af086efe2014571afaRafael Espindola
2131599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(D, Attr.getRange(),
2132599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Platform,
2133599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Introduced.Version,
2134599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Deprecated.Version,
2135599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Obsoleted.Version,
2136599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      IsUnavailable, Str);
2137599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
2138599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
213998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola}
214098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
2141599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaVisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
2142599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                          VisibilityAttr::VisibilityType Vis) {
2143dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola  if (isa<TypedefNameDecl>(D)) {
2144dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "visibility";
2145599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return NULL;
2146dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola  }
214798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VisibilityAttr *ExistingAttr = D->getAttr<VisibilityAttr>();
214898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  if (ExistingAttr) {
214998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    VisibilityAttr::VisibilityType ExistingVis = ExistingAttr->getVisibility();
215098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    if (ExistingVis == Vis)
2151599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola      return NULL;
215298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    Diag(ExistingAttr->getLocation(), diag::err_mismatched_visibility);
215398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    Diag(Range.getBegin(), diag::note_previous_attribute);
215498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    D->dropAttr<VisibilityAttr>();
215598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  }
2156599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return ::new (Context) VisibilityAttr(Range, Context, Vis);
21570a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
21580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
21591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
21611731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
21626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2163bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21647a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
21656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
21666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21685cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
2169fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
21703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
21716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
2175cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
2176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2177c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
2178cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
2179c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
2180cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
2181c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
2182cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
21834188760f6bb20f91c6883dffd89204419f852deeJohn McCall  else if (TypeStr == "protected") {
21844188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // Complain about attempts to use protected visibility on targets
21854188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // (like Darwin) that don't support it.
21864188760f6bb20f91c6883dffd89204419f852deeJohn McCall    if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
21874188760f6bb20f91c6883dffd89204419f852deeJohn McCall      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
21884188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Default;
21894188760f6bb20f91c6883dffd89204419f852deeJohn McCall    } else {
21904188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Protected;
21914188760f6bb20f91c6883dffd89204419f852deeJohn McCall    }
21924188760f6bb20f91c6883dffd89204419f852deeJohn McCall  } else {
219308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
21946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2197599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type);
2198599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
2199599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
22006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
22016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
22031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
2204d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
2205d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
220687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
2207883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
2208d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
2209d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
2210d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
221187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
221287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
221387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2214d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
2215d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
221687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2217d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
221887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2219d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
2220d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
2221d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
22225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
2223d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
2224d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
2225d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
2226d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
2227d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
2228d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
2229d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
2230d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
2231d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
2232d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
2233d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
2234d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
2235d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
2236d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
2237d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
2238d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
223987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
2240d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
2241d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
2242d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
224308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  if (family == ObjCMethodFamilyAttr::OMF_init &&
2244f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
2245f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
2246f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
2247f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
2248f85e193739c953358c865005855253af4f68a497John McCall    return;
2249f85e193739c953358c865005855253af4f68a497John McCall  }
2250f85e193739c953358c865005855253af4f68a497John McCall
2251768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
2252f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
2253d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
2254d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
22551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
22561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
22571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
22580db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
2259bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22600db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
22610db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
22620db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
22630db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
22640db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
2265bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2266768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
22670db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
22680db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
22691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
2270fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
22712b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2272fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
2273fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
2274162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2275fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
22769af9122067f1334806a5f22ce907a3209490d506Ted Kremenek    if (!T->isCARCBridgableType()) {
2277fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2278fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
2279fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
2280fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
22813427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
22823427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian    QualType T = PD->getType();
22839af9122067f1334806a5f22ce907a3209490d506Ted Kremenek    if (!T->isCARCBridgableType()) {
22843427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian      S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
22853427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian      return;
22863427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian    }
22873427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian  }
22883427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian  else {
2289f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // It is okay to include this attribute on properties, e.g.:
2290f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
2291f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2292f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
2293f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // In this case it follows tradition and suppresses an error in the above
229408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    // case.
22959b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
2296f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  }
2297768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
2298fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
2299fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
2300bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
23011b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2302f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
23032b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2304f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
2305f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
2306f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
2307f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
2308f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
2309f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
2310f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
2311f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
2312768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
2313f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
2314f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
23151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2316bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2317fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
23183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
23199eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
23209eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2321bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23229eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
23233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
23249eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
23259eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2326bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2327cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
232892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
23299eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
23309eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
2331fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
23323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
23339eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
23349eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2335bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2336768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
23379eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
23389eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
23391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2340770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
2341770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
2342bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
2343770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
2344bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2345bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23463323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
2347770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
23487a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
2349770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
2350ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2351ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
2352fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
2354770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2355770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2356bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23573323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
2358fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2359fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
2360770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2361770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
23623323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
23633323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
2364770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2365770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
23663323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
2367770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
23687a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
2369770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
2370ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2371ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
2372fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
23733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
2374770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2375770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2376770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
2377bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23783323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
2379770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
2380770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
2381fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2382fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
2383770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2384770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2385770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2386770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
238787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
23883323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
2389897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
2390897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
2391897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
2392897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
2393bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2394897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
23953bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2396770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2397bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
239887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
2399770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
24003bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2401770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
24022f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
2403a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
2404a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    if (!BD->isVariadic()) {
2405a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2406a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      return;
2407a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    }
240887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
24092f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
2410daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
241187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
2412f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
24132f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
24143bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
24153bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
24162f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
24172f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
2418ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
24192f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2420883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
24212f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
24222f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
2423770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
2424fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2425883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
2426770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
2427770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2428768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
2429f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
2430770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
2431770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
24321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
2433026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
24341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2435026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
2436026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
2437f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
2438026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2439883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
2440026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
2441026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
2442bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2443f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
2444f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2445f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
2446f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
2447f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
2448f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2449f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
2450f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2451f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
2452f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
2453f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
245408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
2455768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
2456026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
2457026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
24581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
246087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
246187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
24626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24646e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
246587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
246613c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    if (isa<CXXRecordDecl>(D)) {
246713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
246813c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      return;
246913c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    }
247087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
247187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
2472f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
2473f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
2474f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
247587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
2476332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
2477332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
2478332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
247987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
24806e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
24816e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
2482bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2483768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
24846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24876e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
24881731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
24896e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
24901731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
24916e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
24926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
24936e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
24940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
24950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
24960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
24970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
24980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
2499def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2500bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
250190eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2502def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
2503def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
2504c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2505883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
25066e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
25076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
25086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
25096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
2510768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
25116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
25126e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
25130df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner// Handles reqd_work_group_size and work_group_size_hint.
25140df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattnerstatic void handleWorkGroupSize(Sema &S, Decl *D,
25154ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky                                const AttributeList &Attr) {
251608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  assert(Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize
25170df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      || Attr.getKind() == AttributeList::AT_WorkGroupSizeHint);
25180df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner
25196f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
25200df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  if (!checkAttributeNumArgs(S, Attr, 3)) return;
25216f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
25226f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
25236f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
25247a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
25256f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
2526ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2527ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
25286f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
25290df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner        << Attr.getName()->getName() << E->getSourceRange();
25306f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
25316f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
25326f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
25336f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
25340df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner
25350df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize
25360df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner    && D->hasAttr<ReqdWorkGroupSizeAttr>()) {
25370df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      ReqdWorkGroupSizeAttr *A = D->getAttr<ReqdWorkGroupSizeAttr>();
25380df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      if (!(A->getXDim() == WGSize[0] &&
25390df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner            A->getYDim() == WGSize[1] &&
25400df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner            A->getZDim() == WGSize[2])) {
25410df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner        S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
25420df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner          Attr.getName();
25430df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      }
25440df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  }
25450df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner
25460df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  if (Attr.getKind() == AttributeList::AT_WorkGroupSizeHint
25470df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner    && D->hasAttr<WorkGroupSizeHintAttr>()) {
25480df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      WorkGroupSizeHintAttr *A = D->getAttr<WorkGroupSizeHintAttr>();
25490df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      if (!(A->getXDim() == WGSize[0] &&
25500df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner            A->getYDim() == WGSize[1] &&
25510df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner            A->getZDim() == WGSize[2])) {
25520df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner        S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
25530df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner          Attr.getName();
25540df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner      }
25550df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  }
25560df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner
25570df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize)
25580df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner    D->addAttr(::new (S.Context)
25590df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner                 ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
25600df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner                                       WGSize[0], WGSize[1], WGSize[2]));
25610df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  else
25620df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner    D->addAttr(::new (S.Context)
25630df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner                 WorkGroupSizeHintAttr(Attr.getRange(), S.Context,
25640df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner                                       WGSize[0], WGSize[1], WGSize[2]));
25656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
25666f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
2567599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaSectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
2568599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                    StringRef Name) {
2569420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola  if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
2570420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola    if (ExistingAttr->getName() == Name)
2571599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola      return NULL;
2572420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola    Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section);
2573420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola    Diag(Range.getBegin(), diag::note_previous_attribute);
2574599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return NULL;
2575420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola  }
2576599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return ::new (Context) SectionAttr(Range, Context, Name);
25776f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
25786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
25791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
258017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
25811731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
258217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
258317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
258417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
258517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
25867a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2587797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
258817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
2589797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
259017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
259117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
25921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2593797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
2594bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2595a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2596a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2597a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2598797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2599797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
26001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2601a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2602a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2603a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2604a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2605a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2606599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(),
2607599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                            SE->getString());
2608599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
2609599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
261017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
261117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
26126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
26146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2615831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
26163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
26176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
261908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
262087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2621b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2622ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2623b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2624768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2625b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
26266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
26276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2629232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2630831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
26313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2632232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2633232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2634bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
263587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2636b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2637ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2638b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2639768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2640b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2641232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2642232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
26431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2644232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
26451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2646232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2647bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2648768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2649232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2650232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
26511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2652bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2653f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2654f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2655f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2656bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2657f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2658f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2659f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2660f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2661bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
266287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2663bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2664f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2665f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2666f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2667f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2668bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2669f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2670c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2671f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2672f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2673f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2674f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2675f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2676f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2677f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2678f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2679bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2680f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2681f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2682f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2683f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2684f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2685f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2686f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2687f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2688f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2689f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2690f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2691f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2692f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2693f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2694bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
269589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
269689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
269789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
269889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2699b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2700b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2701f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
270289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
270389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
270489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
270589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2706bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2707768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
27085f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
2709f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2710f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2711bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2712bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
27131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
27141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
27155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
27161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
271787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
27185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2719883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
27205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
27215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
272207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
272307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
272407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
272587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
272687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
27275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
272807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
27295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
27307a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
27315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2732ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2733ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
27345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
27355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
27365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
27375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2738bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
27395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
27405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
27415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
27425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
27435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2744bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
27455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2746bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
274707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
274807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
274907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
275007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
275107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
275207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
275307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
275407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
275507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
27565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
275787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2758bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
27595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
27605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
27615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
27625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
27636217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
27645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
27655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2766bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
27675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
27685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2769bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
277087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
27715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
27725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
27735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
27746217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
27755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
27765b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2777bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
27785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
27795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2780bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2781bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2782768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
278307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
27845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
27855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
27862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
27872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
27882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
27892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
27902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
27913c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
27922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
27932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
27942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
27952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
27962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
27975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
2798c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer  return llvm::StringSwitch<FormatAttrKind>(Format)
2799c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    // Check for formats that get handled specially.
2800c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("NSString", NSStringFormat)
2801c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("CFString", CFStringFormat)
2802c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("strftime", StrftimeFormat)
2803c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer
2804c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    // Otherwise, check for supported formats.
2805c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
2806c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
2807c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("kprintf", SupportedFormat) // OpenBSD.
2808c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer
2809c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
2810c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Default(InvalidFormat);
28112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
28122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2813521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2814521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
28151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
28161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
28174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!S.getLangOpts().CPlusPlus) {
2818521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2819521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2820521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
282108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
282287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2823b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2824b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2825b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2826b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
282787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2828b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2829b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2830b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2831b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2832b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2833b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2834b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
283508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
2836521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2837521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2838521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2839521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2840521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
28417a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
284208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
2843521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2844521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2845521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2846521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2847521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2848521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2849521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2850521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
28519f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2852521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2853521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2854521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2855521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2856521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2857521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2858768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2859f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2860521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2861521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2862599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaFormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
2863599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                  int FormatIdx, int FirstArg) {
2864bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola  // Check whether we already have an equivalent format attribute.
2865bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola  for (specific_attr_iterator<FormatAttr>
2866bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola         i = D->specific_attr_begin<FormatAttr>(),
2867bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola         e = D->specific_attr_end<FormatAttr>();
2868bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola       i != e ; ++i) {
2869bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola    FormatAttr *f = *i;
2870bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola    if (f->getType() == Format &&
2871bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola        f->getFormatIdx() == FormatIdx &&
2872bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola        f->getFirstArg() == FirstArg) {
2873bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola      // If we don't have a valid location for this attribute, adopt the
2874bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola      // location.
2875bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola      if (f->getLocation().isInvalid())
2876bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola        f->setRange(Range);
2877599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola      return NULL;
2878bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola    }
2879bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola  }
2880bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola
2881599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
2882599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                    FirstArg);
2883bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola}
2884bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola
2885bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2886bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
28871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
28886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2889545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2890fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
28913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
28926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
28946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2895545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
28963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
28976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
28996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
290087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2901fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2902883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
29036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
290607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
290707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
290887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
290987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
29106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
29116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
29136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
29152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
29162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
29172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
29182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
29192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
292008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
29213c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
29223c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
292308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
29242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2925fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
292601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
29276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
29317a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2932803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2933ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2934ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2935fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
29363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
29376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2941fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
29423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
29436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
29476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2948bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
29494a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
29504a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
295107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
295207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
295307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
29544a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
29554a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
29564a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
29574a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
29581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
29596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
296087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
29616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2963085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2964fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2965fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2966085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2967085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
29682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2969390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2970390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2971803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2972390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2973fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2974fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
29756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2976bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
29776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
29786217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2979390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2980fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2981fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
29826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
29867a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2987803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2988ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2989ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2990fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
29913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
29926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
29946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
29966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
299787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
29986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
29996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
300087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
30016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
30026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
30036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
30046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
30053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
30063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
30072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
30086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
3009fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
3010fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
30116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
30126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
30136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
30146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
3015fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
30163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
30176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
30186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
30196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3020599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format,
3021cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
3022599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                          FirstArg.getZExtValue());
3023599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
3024599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
30256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
30266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
30271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
30281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
30296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
30301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
30316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
30321731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
30336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
30340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
30350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
303687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
30370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
30380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
30390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
304087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
30410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
30420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
3043fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3044883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
30456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
30466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
30476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
30485e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall  if (!RD->isCompleteDefinition()) {
3049bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
30500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
30510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
30520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
30530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
305417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
305517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
30560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
30570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
30580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
30590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
3060bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
30610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
30620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
306390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
3064bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
306590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
306690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
30670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
30680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
3069bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
30700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
30710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
30720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
30730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
30740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
30750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
30760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
30770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
3078bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
30790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
3080bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
30810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
30820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
30830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
3084bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
30850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
30860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
3087bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
3088bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
3089bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
30906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3091768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
30926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
30936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
30941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
30956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
30961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
30976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
30981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
30997a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
3100797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
3101bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
31026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
31036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
31046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
3105797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
31066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
31076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
310877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
310977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
311077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
311177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
311277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
311377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
311477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
311577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
3116768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
3117f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
31186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
31196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
31201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
31216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
3122545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
31233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
31246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
31256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3126fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman
3127bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
3128bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
3129bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
31306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3131545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
313208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
3133fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman               true, 0, Attr.isDeclspecAttribute()));
31344ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
31354ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
31364ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
313708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0),
3138fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                   Attr.isDeclspecAttribute());
31394ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
31404ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
314108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaovoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
3142fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                          bool isDeclSpec) {
31430b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  // FIXME: Handle pack-expansions here.
31440b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  if (DiagnoseUnexpandedParameterPack(E))
31450b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne    return;
31460b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne
31474ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
31484ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
314908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E,
3150fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                                           isDeclSpec));
31516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
31526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3154768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
3155cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
315649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
3157ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor  ExprResult ICE
3158ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor    = VerifyIntegerConstantExpression(E, &Alignment,
3159ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor        diag::err_aligned_attribute_argument_not_int,
3160ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor        /*AllowFold*/ false);
3161282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  if (ICE.isInvalid())
316249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
3163396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
31644ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
31654ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
3166396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
3167396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
3168fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman  if (isDeclSpec) {
3169fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman    // We've already verified it's a power of 2, now let's make sure it's
3170fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman    // 8192 or less.
3171fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman    if (Alignment.getZExtValue() > 8192) {
317208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao      Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192)
3173fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman        << E->getSourceRange();
3174fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman      return;
3175fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman    }
3176fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman  }
3177396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
317808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take(),
3179fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                                         isDeclSpec));
3180cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
3181cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
318208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaovoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
3183fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                          bool isDeclSpec) {
3184cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
3185cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
318608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS,
3187fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman                                         isDeclSpec));
3188cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
31896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3190fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3191d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
3192bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
3193fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
3194bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
3195bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
3196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
31971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3198fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
3199fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
3200fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3201fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
32021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
3203fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
32041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3205fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3206fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
3207fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
32080b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
3209fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3210fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3211210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
32125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
3213fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3214fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
3215210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
3216210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
3217fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3218fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
3219fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
322073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
3221210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
3222fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
322373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
322473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
322573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
322673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
322773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
322873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
322973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
323073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
323173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
323273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
323373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
323473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
323573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
323673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
323773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
323873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
3239fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3240fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
3241fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
3242fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
3243210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
3244bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3245210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
3246bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
3247fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3248fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
3249210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
3250bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3251fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3252fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3253fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3254fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
3255162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
3256fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
3257fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
3258fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
3259fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
3260fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
3261768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
3262fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3263fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
326473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
3265183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
326673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
326773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
32682ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
326973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
327073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
327173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
327273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
327373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
327473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
327573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
327673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
327773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
3278390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
3279390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
3280390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
3281390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
3282f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
3283f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
3284fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
3285fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
3286fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
32873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
3288fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3289fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
32903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3291fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3292fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
329373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
329473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
329573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
329673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
3297fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
32980b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
3299fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
33000b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
3301fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3302fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
330373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
330473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
330573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
330673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
3307fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
33080b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
3309fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
33100b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
3311fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3312fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
3313fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
33140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
3315fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
33160b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
3317fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
33180b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
3319fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3320fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
3321fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
33220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
3323fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
3324bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
3325aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
3326aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
3327aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
3328fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
3329bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
3330aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
3331aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
3332aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
3333fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
333473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
333573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
333673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
3337f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
3338f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
3339f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3340f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
3341f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
3342f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
3343f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
3344f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
3345f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
334673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
3347fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3348fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
334973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
335073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
3351fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3352fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3353fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
3354162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
3355ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
3356a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
3357ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
3358fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
3359fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
33600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
33611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3362d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
33631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
3364d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
3365e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
336678d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
336778d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky    if (!VD->hasGlobalStorage())
336878d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky      S.Diag(Attr.getLoc(),
336978d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky             diag::warn_attribute_requires_functions_or_static_globals)
337078d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky        << Attr.getName();
337178d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky  } else if (!isFunctionOrMethod(D)) {
337278d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky    S.Diag(Attr.getLoc(),
337378d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky           diag::warn_attribute_requires_functions_or_static_globals)
337478d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky      << Attr.getName();
3375d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
3376d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
3377bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3378768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
3379d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
3380d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
33811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
33825bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
33831731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
33845bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
33851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3386bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
338787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
33885bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3389883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
33905bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
33915bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
3392bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3393768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
33945bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
33955bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
33961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
33971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
33987255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
33991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
34007255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
34011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
34027255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
340387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
34047255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3405883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
34067255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
34077255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
34087255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
3409768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
3410f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
34117255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
34127255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
34130557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hinesstatic void handleKernelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
34140557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines  if (S.LangOpts.Renderscript) {
34150557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines    D->addAttr(::new (S.Context) KernelAttr(Attr.getRange(), S.Context));
34160557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines  } else {
34170557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "kernel";
34180557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines  }
34190557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines}
34200557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines
34211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3422ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3423ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
3424831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
3425ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3426ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3427ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3428ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
342987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
3430ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3431883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
3432ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3433ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3434ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3435768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
3436ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3437ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
3438ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3439ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3440ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
34411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3442ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3443ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
3444ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
3445ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3446ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3447ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3448ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
344987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
3450ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3451883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
3452ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3453ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3454ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3455768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
3456ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3457ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
3458ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3459ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3460ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
34611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3462ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3463ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
34641731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3465ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3466ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
346787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
3468ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3469883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
3470ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3471ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3472ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
347387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
34742c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
3475723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
34762c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
34772c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
34782c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
34792c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
34802c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
34812c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
34822c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
34832c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
34842c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
34852c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
34862c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
34872c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
3488768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
3489ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3490ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
3491ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3492ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3493ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
34941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3495ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3496ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
34971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3498ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
34991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3500ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
350187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
3502ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3503883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
3504ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3505ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3506ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3507768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
3508ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3509ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
3510ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3511ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3512ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
35131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3514ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3515ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
35161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3517ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
35181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3519ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
352087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
3521ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3522883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
3523ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3524ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3525ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3526768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
3527ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3528ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
3529ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3530ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3531ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
35321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
353326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
35341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
353526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
3536bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
353787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
3538c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
353926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3540883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
354126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
354226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
3543bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
35440130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
3545cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
3546c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
3547c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
3548bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3549768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
355026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
355126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
35521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
355387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3554711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
355587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
3556e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3557711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
355887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
3559711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3560e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
356187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
356287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
356387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3564711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3565711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3566711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
356787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
35688e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_FastCall:
3569768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
3570e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
35718e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_StdCall:
3572768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
3573e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
35748e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ThisCall:
3575768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
357604633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
35778e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CDecl:
3578768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
3579e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
35808e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pascal:
3581768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
358252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
35838e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pcs: {
3584414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
35859071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer    switch (CC) {
35869071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer    case CC_AAPCS:
3587414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
35889071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer      break;
35899071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer    case CC_AAPCS_VFP:
3590414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
35919071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer      break;
35929071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer    default:
35939071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer      llvm_unreachable("unexpected calling convention in pcs attribute");
3594414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3595414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
3596768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
3597414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3598e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
3599e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
3600e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
3601e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
3602e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
36031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
360456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
3605768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3606f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
3607f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
3608711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
3609711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
3610711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3611711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3612fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer  unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0;
3613fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer  if (attr.getNumArgs() != ReqArgs || attr.getParameterName()) {
3614fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << ReqArgs;
3615711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
3616711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3617ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
361855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3619414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3620414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3621711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
36228e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CDecl: CC = CC_C; break;
36238e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
36248e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;
36258e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;
36268e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pascal: CC = CC_X86Pascal; break;
36278e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pcs: {
3628414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3629414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
36305cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3631414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3632414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3633414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3634414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3635414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3636414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
36375f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3638414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3639414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3640414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3641414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3642414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3643414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3644414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3645fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer
3646fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer    attr.setInvalid();
3647fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer    Diag(attr.getLoc(), diag::err_invalid_pcs);
3648fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer    return true;
3649414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
36507530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("unexpected attribute kind");
3651711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3652711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3653711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3654711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3655711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
36561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
365787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3658711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3659711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
366087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3661711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3662711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
366387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
366487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
366587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3666ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3667ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
366855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3669768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3670711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3671711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3672711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3673711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
367487c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
367587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3676711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3677711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
367887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
367987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
368087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3681711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3682711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3683711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
368487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
368555d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3686ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3687711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
368887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
368955d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
369087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3691711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
369255d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
369355d3aaf9a537888734762170823daf750ea9036dEli Friedman
3694bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
369587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
369655d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
369787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3698711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
369955d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
370055d3aaf9a537888734762170823daf750ea9036dEli Friedman
3701711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3702bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
370387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3704bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
370587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3706711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
370755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
370855d3aaf9a537888734762170823daf750ea9036dEli Friedman
3709711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3710ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3711ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
37121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
37137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
37147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
37157b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3716bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3717bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
37187b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
37197b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
37207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
372187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
37227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3723883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
37247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
37257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
37267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
37277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
37287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
37297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
37307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
37317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
37327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
37337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
37347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
37357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
37367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
37377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
37387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
37397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
37407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
37417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
37427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
37437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
37447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
37457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
37467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
37477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
37487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3749768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
37507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
37517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
37527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
37537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
37547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
37557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
37567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
37570d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenkostatic void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
37580d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                          const AttributeList &Attr) {
37590d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  StringRef AttrName = Attr.getName()->getName();
37600d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  if (!Attr.getParameterName()) {
37610d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier)
37620d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko      << Attr.getName() << /* arg num = */ 1;
37630d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    return;
37640d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  }
37650d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
37660d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  if (Attr.getNumArgs() != 2) {
37670d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
37680d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko      << /* required args = */ 3;
37690d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    return;
37700d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  }
37710d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
37720d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  IdentifierInfo *ArgumentKind = Attr.getParameterName();
37730d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
37740d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
37750d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
37760d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko      << Attr.getName() << ExpectedFunctionOrMethod;
37770d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    return;
37780d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  }
37790d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
37800d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  uint64_t ArgumentIdx;
37810d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
37820d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                          Attr.getLoc(), 2,
37830d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                          Attr.getArg(0), ArgumentIdx))
37840d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    return;
37850d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
37860d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  uint64_t TypeTagIdx;
37870d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
37880d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                          Attr.getLoc(), 3,
37890d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                          Attr.getArg(1), TypeTagIdx))
37900d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    return;
37910d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
37920d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  bool IsPointer = (AttrName == "pointer_with_type_tag");
37930d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  if (IsPointer) {
37940d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    // Ensure that buffer has a pointer type.
37950d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    QualType BufferTy = getFunctionOrMethodArgType(D, ArgumentIdx);
37960d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    if (!BufferTy->isPointerType()) {
37970d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko      S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only)
37980d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko        << AttrName;
37990d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    }
38000d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  }
38010d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
38020d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(Attr.getRange(),
38030d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                                       S.Context,
38040d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                                       ArgumentKind,
38050d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                                       ArgumentIdx,
38060d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                                       TypeTagIdx,
38070d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                                       IsPointer));
38080d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko}
38090d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
38100d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenkostatic void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
38110d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                         const AttributeList &Attr) {
38120d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  IdentifierInfo *PointerKind = Attr.getParameterName();
38130d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  if (!PointerKind) {
38140d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier)
38150d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko      << "type_tag_for_datatype" << 1;
38160d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    return;
38170d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  }
38180d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
38190d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL);
38200d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
38210d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
38220d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                  Attr.getRange(),
38230d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                  S.Context,
38240d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                  PointerKind,
38250d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                  MatchingCType,
38260d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                  Attr.getLayoutCompatible(),
38270d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko                                  Attr.getMustBeNull()));
38280d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko}
38290d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
38300744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3831b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3832b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3833b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3834c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
383508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  return type->isDependentType() ||
383608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao         type->isObjCObjectPointerType() ||
38376c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         S.Context.isObjCNSObjectType(type);
3838c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3839c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
384008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  return type->isDependentType() ||
384108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao         type->isPointerType() ||
38426c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         isValidSubjectOfNSAttribute(S, type);
3843c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3844c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
38451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
384687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3847c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
384887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3849768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3850c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3851c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3852c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3853c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
38548e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  if (Attr.getKind() == AttributeList::AT_NSConsumed) {
3855c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3856c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3857c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3858c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3859c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3860c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3861c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3862c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
386387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3864768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3865c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3866c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3867c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3868c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3869768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3870c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3871768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3872c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3873c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
38741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
38751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
387687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
387787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3878768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3879c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3880c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3881c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3882768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3883c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3884c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
38851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
38861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3887b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3888c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3889bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
389087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3891c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
38924e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
38938e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt           (Attr.getKind() == AttributeList::AT_NSReturnsRetained))
3894f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
3895a23bd4cec36d7f29065418f84ef48395fcbe6254Fariborz Jahanian  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3896a23bd4cec36d7f29065418f84ef48395fcbe6254Fariborz Jahanian    returnType = PD->getType();
389787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3898c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
38995dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
390087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3901768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3902883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3903b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3904b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3905bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3906c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3907c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
390887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
39097530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("invalid ownership attribute");
39108e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsAutoreleased:
39118e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsRetained:
39128e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsNotRetained:
3913c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3914c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3915c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3916c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
39178e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFReturnsRetained:
39188e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFReturnsNotRetained:
3919c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3920c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3921c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3922c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3923c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3924c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
392587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3926768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
39285dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3929bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
393087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3931b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3932b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
39338e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_NSReturnsAutoreleased:
3934768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3935c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3936c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
39378e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_CFReturnsNotRetained:
3938768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3939f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
394031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
39418e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_NSReturnsNotRetained:
3942768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3943f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
394431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
39458e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_CFReturnsRetained:
3946768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3947f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3948b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
39498e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_NSReturnsRetained:
3950768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3951f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3952b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3953b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3954b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3955b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3956dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3957dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3958dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3959dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3960dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3961dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
396294d55d7ecdd693788a8f3910a0da1b5ecdaa8a86Fariborz Jahanian  if (!method) {
39630e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3964f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
3965dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3966dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3967dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3968dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3969dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
397008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
3971f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3972f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3973dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3974dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3975dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3976dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3977dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3978dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3979dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3980dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3981dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3982768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3983dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3984dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3985841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanianstatic void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
3986841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian                                        const AttributeList &attr) {
3987841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  SourceLocation loc = attr.getLoc();
3988841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3989841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian
3990841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  if (!method) {
3991841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian   S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3992841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian   << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
3993841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian    return;
3994841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  }
3995841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  DeclContext *DC = method->getDeclContext();
3996841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) {
3997841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian    S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
3998841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian    << attr.getName() << 0;
3999841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian    S.Diag(PDecl->getLocation(), diag::note_protocol_decl);
4000841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian    return;
4001841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  }
4002841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  if (method->getMethodFamily() == OMF_dealloc) {
4003841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian    S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4004841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian    << attr.getName() << 1;
4005841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian    return;
4006841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  }
4007841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian
4008841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  method->addAttr(
4009841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian    ::new (S.Context) ObjCRequiresSuperAttr(attr.getRange(), S.Context));
4010841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian}
4011841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian
40128dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
40138dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
40148dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
40158dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4016f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << A.getRange() << A.getName() << ExpectedFunction;
40178dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
40188dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
40198dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
40208e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  bool IsAudited = (A.getKind() == AttributeList::AT_CFAuditedTransfer);
40218dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
40228dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
40238dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
40248dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
40258dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
40268dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
40278dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
40288dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
40298dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
40308dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
40318dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
40328dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
40338dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
40348dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
40358dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
40368dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
40378dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
40388dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
40398dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
40408dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
40418dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
40428dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
40438dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
40448dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
40458dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
40468dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
4047fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
4048fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
4049fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
4050fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
4051fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4052f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedStruct;
4053fe98da0fa352462c02db037360788748f95466f7John McCall  }
4054fe98da0fa352462c02db037360788748f95466f7John McCall
4055fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
4056fe98da0fa352462c02db037360788748f95466f7John McCall
4057fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
4058fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
4059fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
40604e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (ParmName && S.getLangOpts().ObjC1) {
4061fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
4062fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
4063fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
4064fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
4065fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
4066fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
4067fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
4068fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
4069fe98da0fa352462c02db037360788748f95466f7John McCall      }
4070fe98da0fa352462c02db037360788748f95466f7John McCall    }
4071fe98da0fa352462c02db037360788748f95466f7John McCall  }
4072fe98da0fa352462c02db037360788748f95466f7John McCall
4073fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
4074fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
4075fe98da0fa352462c02db037360788748f95466f7John McCall}
4076fe98da0fa352462c02db037360788748f95466f7John McCall
40771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
40781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
407987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
4080f85e193739c953358c865005855253af4f68a497John McCall
408187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4082f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    << Attr.getRange() << Attr.getName() << ExpectedVariable;
4083f85e193739c953358c865005855253af4f68a497John McCall}
4084f85e193739c953358c865005855253af4f68a497John McCall
40851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
40861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
408787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
408887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4089f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedVariable;
4090f85e193739c953358c865005855253af4f68a497John McCall    return;
4091f85e193739c953358c865005855253af4f68a497John McCall  }
4092f85e193739c953358c865005855253af4f68a497John McCall
409387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
4094f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
4095f85e193739c953358c865005855253af4f68a497John McCall
4096f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
4097f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
409887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
4099f85e193739c953358c865005855253af4f68a497John McCall      << type;
4100f85e193739c953358c865005855253af4f68a497John McCall    return;
4101f85e193739c953358c865005855253af4f68a497John McCall  }
4102f85e193739c953358c865005855253af4f68a497John McCall
4103f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
4104f85e193739c953358c865005855253af4f68a497John McCall
4105f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
4106f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
4107f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
4108f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
4109f85e193739c953358c865005855253af4f68a497John McCall
4110f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
4111f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
4112f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
4113f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
4114f85e193739c953358c865005855253af4f68a497John McCall    break;
4115f85e193739c953358c865005855253af4f68a497John McCall
4116f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
4117f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
4118f85e193739c953358c865005855253af4f68a497John McCall    break;
4119f85e193739c953358c865005855253af4f68a497John McCall
4120f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
4121f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
412287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
4123f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
4124f85e193739c953358c865005855253af4f68a497John McCall    break;
4125f85e193739c953358c865005855253af4f68a497John McCall  }
4126f85e193739c953358c865005855253af4f68a497John McCall
412787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
4128768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
4129f85e193739c953358c865005855253af4f68a497John McCall}
4130f85e193739c953358c865005855253af4f68a497John McCall
413111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
413211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
413311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
413411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
41351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
413662ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
413711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
41381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
413911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
41401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
414111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
414211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
41435cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
4144d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
4145d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
4146d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
4147d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
4148d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
41495f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
4150d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
4151d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
4152d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
4153f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
4154d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
4155d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
4156d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4157d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
4158d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
4159d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
4160d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4161d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
4162d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
4163d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
4164f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
4165d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
41665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
4167f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
4168f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
4169f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
4170f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
4171d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
4172d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
4173d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4174d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
4175d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
4176d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
4177d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4178d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
4179d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
4180d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
4181d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
418211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
4183768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
418411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
4185d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
418611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
4187f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
4188f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
4189c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallstatic void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4190c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  if (S.LangOpts.MicrosoftExt) {
4191c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    AttributeList::Kind Kind = Attr.getKind();
41928e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    if (Kind == AttributeList::AT_SingleInheritance)
4193c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4194c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context));
41958e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    else if (Kind == AttributeList::AT_MultipleInheritance)
4196c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4197c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context));
41988e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    else if (Kind == AttributeList::AT_VirtualInheritance)
4199c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4200c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context));
4201c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  } else
4202c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4203c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall}
4204c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
4205c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallstatic void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4206c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  if (S.LangOpts.MicrosoftExt) {
4207c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    AttributeList::Kind Kind = Attr.getKind();
42088e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    if (Kind == AttributeList::AT_Ptr32)
4209c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4210c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context));
42118e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    else if (Kind == AttributeList::AT_Ptr64)
4212c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4213c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context));
42148e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    else if (Kind == AttributeList::AT_Win64)
4215c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
4216c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) Win64Attr(Attr.getRange(), S.Context));
4217c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  } else
4218c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4219c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall}
4220c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
4221adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencerstatic void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4222adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer  if (S.LangOpts.MicrosoftExt)
4223adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    D->addAttr(::new (S.Context) ForceInlineAttr(Attr.getRange(), S.Context));
4224adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer  else
4225adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4226adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer}
4227adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer
4228b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
42290744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
42300744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
42310744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
42321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
42331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
423460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
42358e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDADevice:  handleDeviceAttr      (S, D, Attr); break;
42368e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDAHost:    handleHostAttr        (S, D, Attr); break;
42378e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Overloadable:handleOverloadableAttr(S, D, Attr); break;
4238e559b0dc6de871f73eb4db6378c65552e95e83e7Shih-wei Liao  case AttributeList::AT_Kernel:      handleKernelAttr      (S, D, Attr); break;
423960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
424060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
424160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
424260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
4243e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
42441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
42451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
4246803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
42478e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_IBAction:          handleIBAction(S, D, Attr); break;
42488e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
42498e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    case AttributeList::AT_IBOutletCollection:
42501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
42518e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AddressSpace:
42528e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_OpenCLImageAccess:
42538e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCGC:
42548e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_VectorSize:
42558e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NeonVectorType:
42568e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NeonPolyVectorType:
4257bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
4258bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
4259803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
42608e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDADevice:
42618e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDAHost:
42628e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Overloadable:
426308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  case AttributeList::AT_Kernel:
426460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
426560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
426660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
42678e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Alias:       handleAliasAttr       (S, D, Attr); break;
42688e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Aligned:     handleAlignedAttr     (S, D, Attr); break;
42698e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AllocSize:   handleAllocSizeAttr   (S, D, Attr); break;
42708e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AlwaysInline:
42711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
42728e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AnalyzerNoReturn:
42731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
42745e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg  case AttributeList::AT_TLSModel:    handleTLSModelAttr    (S, D, Attr); break;
42758e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Annotate:    handleAnnotateAttr    (S, D, Attr); break;
42768e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break;
42778e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CarriesDependency:
42781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
42798e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Common:      handleCommonAttr      (S, D, Attr); break;
42808e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDAConstant:handleConstantAttr    (S, D, Attr); break;
42818e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Constructor: handleConstructorAttr (S, D, Attr); break;
42828e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Deprecated:
4283bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    handleAttrWithMessage<DeprecatedAttr>(S, D, Attr, "deprecated");
4284bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    break;
42858e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Destructor:  handleDestructorAttr  (S, D, Attr); break;
42868e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ExtVectorType:
42871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
42883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
42898e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Format:      handleFormatAttr      (S, D, Attr); break;
42908e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_FormatArg:   handleFormatArgAttr   (S, D, Attr); break;
42918e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDAGlobal:  handleGlobalAttr      (S, D, Attr); break;
42928e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_GNUInline:   handleGNUInlineAttr   (S, D, Attr); break;
42938e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDALaunchBounds:
42941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
42957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
42968e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Mode:        handleModeAttr        (S, D, Attr); break;
42978e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Malloc:      handleMallocAttr      (S, D, Attr); break;
42988e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_MayAlias:    handleMayAliasAttr    (S, D, Attr); break;
42998e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoCommon:    handleNoCommonAttr    (S, D, Attr); break;
43008e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NonNull:     handleNonNullAttr     (S, D, Attr); break;
4301dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
4302dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
4303dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
43041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
43058e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Cold:        handleColdAttr        (S, D, Attr); break;
43068e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Hot:         handleHotAttr         (S, D, Attr); break;
43078e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Naked:       handleNakedAttr       (S, D, Attr); break;
43088e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoReturn:    handleNoReturnAttr    (S, D, Attr); break;
43098e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoThrow:     handleNothrowAttr     (S, D, Attr); break;
43108e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CUDAShared:  handleSharedAttr      (S, D, Attr); break;
43118e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_VecReturn:   handleVecReturnAttr   (S, D, Attr); break;
43128e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt
43138e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCOwnership:
43141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
43158e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCPreciseLifetime:
43161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
4317f85e193739c953358c865005855253af4f68a497John McCall
43188e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCReturnsInnerPointer:
4319dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
4320dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
4321841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian  case AttributeList::AT_ObjCRequiresSuper:
4322841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian      handleObjCRequiresSuperAttr(S, D, Attr); break;
4323841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian
43248e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSBridged:
4325fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
4326fe98da0fa352462c02db037360788748f95466f7John McCall
43278e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFAuditedTransfer:
43288e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFUnknownTransfer:
43298dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
43308dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
4331b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
43328e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFConsumed:
43338e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSConsumed:  handleNSConsumedAttr  (S, D, Attr); break;
43348e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSConsumesSelf:
43351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
4336c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
43378e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsAutoreleased:
43388e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsNotRetained:
43398e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFReturnsNotRetained:
43408e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NSReturnsRetained:
43418e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CFReturnsRetained:
43421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
4343b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
43440df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner  case AttributeList::AT_WorkGroupSizeHint:
43458e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ReqdWorkGroupSize:
43460df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner    handleWorkGroupSize(S, D, Attr); break;
43476f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
434808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  case AttributeList::AT_InitPriority:
43491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
435008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao
43518e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Packed:      handlePackedAttr      (S, D, Attr); break;
43528e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Section:     handleSectionAttr     (S, D, Attr); break;
43538e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Unavailable:
4354bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    handleAttrWithMessage<UnavailableAttr>(S, D, Attr, "unavailable");
4355bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    break;
435608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  case AttributeList::AT_ArcWeakrefUnavailable:
435708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    handleArcWeakrefUnavailableAttr (S, D, Attr);
4358742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
43598e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCRootClass:
4360b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    handleObjCRootClassAttr(S, D, Attr);
4361b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    break;
436208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  case AttributeList::AT_ObjCRequiresPropertyDefs:
436308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
4364e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    break;
43658e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Unused:      handleUnusedAttr      (S, D, Attr); break;
43668e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ReturnsTwice:
4367f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
4368f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
43698e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Used:        handleUsedAttr        (S, D, Attr); break;
43708e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Visibility:  handleVisibilityAttr  (S, D, Attr); break;
43718e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr);
4372026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
43738e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Weak:        handleWeakAttr        (S, D, Attr); break;
43748e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_WeakRef:     handleWeakRefAttr     (S, D, Attr); break;
43758e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_WeakImport:  handleWeakImportAttr  (S, D, Attr); break;
43768e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_TransparentUnion:
43771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
4378803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
43798e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCException:
43801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
43810db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
43828e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCMethodFamily:
43831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
4384d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
43858e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ObjCNSObject:handleObjCNSObject    (S, D, Attr); break;
43868e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Blocks:      handleBlocksAttr      (S, D, Attr); break;
43878e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Sentinel:    handleSentinelAttr    (S, D, Attr); break;
43888e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Const:       handleConstAttr       (S, D, Attr); break;
43898e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pure:        handlePureAttr        (S, D, Attr); break;
43908e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Cleanup:     handleCleanupAttr     (S, D, Attr); break;
43918e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoDebug:     handleNoDebugAttr     (S, D, Attr); break;
43928e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoInline:    handleNoInlineAttr    (S, D, Attr); break;
43938e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Regparm:     handleRegparmAttr     (S, D, Attr); break;
4394bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
439505f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
439605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
43978e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoInstrumentFunction:  // Interacts with -pg.
43981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
43997255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
44008e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_StdCall:
44018e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_CDecl:
44028e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_FastCall:
44038e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ThisCall:
44048e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pascal:
44058e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Pcs:
44061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
440704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
44088e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_OpenCLKernel:
44091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
4410f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
4411c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
4412c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  // Microsoft attributes:
44138e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_MsStruct:
4414c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    handleMsStructAttr(S, D, Attr);
4415c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    break;
44168e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Uuid:
44171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
441811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
44198e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_SingleInheritance:
44208e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_MultipleInheritance:
44218e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_VirtualInheritance:
4422c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    handleInheritanceAttr(S, D, Attr);
4423c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    break;
44248e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Win64:
44258e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Ptr32:
44268e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Ptr64:
4427c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    handlePortabilityAttr(S, D, Attr);
4428c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    break;
44298e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ForceInline:
4430adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    handleForceInlineAttr(S, D, Attr);
4431adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    break;
4432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
44348e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_GuardedVar:
4435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
4436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
44378e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_PtGuardedVar:
4438dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handlePtGuardedVarAttr(S, D, Attr);
4439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
44408e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ScopedLockable:
4441dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleScopedLockableAttr(S, D, Attr);
4442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
44438e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoAddressSafetyAnalysis:
444471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    handleNoAddressSafetyAttr(S, D, Attr);
444571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    break;
44468e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_NoThreadSafetyAnalysis:
4447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
4448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
44498e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_Lockable:
4450fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
4451fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
44528e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_GuardedBy:
4453db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
4454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44558e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_PtGuardedBy:
4456dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handlePtGuardedByAttr(S, D, Attr);
4457db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44588e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ExclusiveLockFunction:
4459dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleExclusiveLockFunctionAttr(S, D, Attr);
4460db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44618e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ExclusiveLocksRequired:
4462dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleExclusiveLocksRequiredAttr(S, D, Attr);
4463db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44648e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_ExclusiveTrylockFunction:
4465dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleExclusiveTrylockFunctionAttr(S, D, Attr);
4466db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44678e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_LockReturned:
4468db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
4469db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44708e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_LocksExcluded:
4471db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
4472db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44738e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_SharedLockFunction:
4474dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleSharedLockFunctionAttr(S, D, Attr);
4475db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44768e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_SharedLocksRequired:
4477dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleSharedLocksRequiredAttr(S, D, Attr);
4478db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44798e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_SharedTrylockFunction:
4480dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleSharedTrylockFunctionAttr(S, D, Attr);
4481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44828e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_UnlockFunction:
4483db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
4484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44858e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AcquiredBefore:
4486dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleAcquiredBeforeAttr(S, D, Attr);
4487db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
44888e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt  case AttributeList::AT_AcquiredAfter:
4489dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han    handleAcquiredAfterAttr(S, D, Attr);
4490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4491fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
44920d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  // Type safety attributes.
44930d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  case AttributeList::AT_ArgumentWithTypeTag:
44940d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    handleArgumentWithTypeTagAttr(S, D, Attr);
44950d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    break;
44960d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko  case AttributeList::AT_TypeTagForDatatype:
44970d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    handleTypeTagForDatatypeAttr(S, D, Attr);
44980d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko    break;
44990d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko
4500803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
450182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
450282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
450382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
450408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao      S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ?
450508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao             diag::warn_unhandled_ms_attribute_ignored :
4506fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman             diag::warn_unknown_attribute_ignored) << Attr.getName();
4507803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
4508803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
4509803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
4510803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
451160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
451260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
451360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
451460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
45151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
45161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
451760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
451860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
451960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
452060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
452108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  // Type attributes are still treated as declaration attributes by
452208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  // ParseMicrosoftTypeAttributes and ParseBorlandTypeAttributes.  We don't
452308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao  // want to process them, however, because we will simply warn about ignoring
4524fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman  // them.  So instead, we will bail out early.
4525fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman  if (Attr.isMSTypespecAttribute())
452660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
452760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
452860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
45291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
453060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
453160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
45321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
453360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
453460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
4535803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
4536803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
4537f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
453860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
453960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
454011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
45411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
454211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
454311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
454411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
454511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
454611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
454760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
454811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
4549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
455011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
4551803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
4552803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
4553803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
45545f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access
45555f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier.
45565f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
45575f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          const AttributeList *AttrList) {
45585f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
45598e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt    if (l->getKind() == AttributeList::AT_Annotate) {
45605f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      handleAnnotateAttr(*this, ASDecl, *l);
45615f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    } else {
45625f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
45635f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      return true;
45645f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    }
45655f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  }
45665f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
45675f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  return false;
45685f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen}
45695f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
4570e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
4571e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
4572e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
4573e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
4574e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
4575e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
4576e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
4577e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4578e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
4579e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
4580e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
4581e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
4582e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
4583e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
4584e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
4585e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
4586e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
4587e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4588e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
4589e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
4590e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
4591e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
4592e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
4593e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
4594e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
4595e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
4596e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
4597e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4598e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
45991dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// \#pragma weak needs a non-definition decl and source may not have one.
4600900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
4601900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
46027b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
4603e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
4604e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
4605900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
4606900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
4607900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
4608900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
4609900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
4610900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
4611900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
4612900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
4613900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
4614900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
4615900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
4616900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
4617900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
4618900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
4619900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
4620c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
4621900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
4622900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
4623900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
4624900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
4625900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
4626900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
4627900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
4628900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
4629900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
4630900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
4631900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
4632900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
46334278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
4634b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
4635e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
4636e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
4637ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
4638a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
463916573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
464016573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
4641b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
4642b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
4643c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
4644b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
4645e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4646e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
4647e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
4648e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
46491dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
4650e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
46517b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
4652c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
4653c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
4654c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
4655c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
4656900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
4657cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
4658cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
4659cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
4660c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
4661c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
4662c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
4663c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
4664c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
4665c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
4666c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
4667c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
4668cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
4669e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4670e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
4671e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
46720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
46730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
46740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
467560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
467660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
4677d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
4678d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
467931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
468031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
468131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
468231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
468331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
468431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
468531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
468631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
468731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
468831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
468931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
469031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
4691d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
4692e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
4693e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
4694e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4695e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
46960744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
46977f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
469860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4699bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
47000744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
47010744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
47020744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
47030744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
47040744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
47050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
470660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4707bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
47080744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
47090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
471060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
47110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
471254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4713f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
4714f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
4715f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
4716f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
4717f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
4718a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
4719a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
4720a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
4721f85e193739c953358c865005855253af4f68a497John McCall    return false;
4722f85e193739c953358c865005855253af4f68a497John McCall
4723f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
4724f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
4725f85e193739c953358c865005855253af4f68a497John McCall}
4726f85e193739c953358c865005855253af4f68a497John McCall
4727f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
4728f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4729f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
4730f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
4731f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
4732f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
4733f85e193739c953358c865005855253af4f68a497John McCall    return;
4734f85e193739c953358c865005855253af4f68a497John McCall  }
47354e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (S.getLangOpts().ObjCAutoRefCount)
4736175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
473748d798ce32447607144db70a484cdb99c1180663Benjamin Kramer      // FIXME: we may want to suppress diagnostics for all
473808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao      // kind of forbidden type messages on unavailable functions.
4739175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
474008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao          diag.getForbiddenTypeDiagnostic() ==
4741175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
4742175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
4743175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
4744175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
4745175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
4746f85e193739c953358c865005855253af4f68a497John McCall
4747f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4748f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4749f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
4750f85e193739c953358c865005855253af4f68a497John McCall}
4751f85e193739c953358c865005855253af4f68a497John McCall
47529257664568bf375b7790131a84d9a4fa30a5b7e3John McCallvoid Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
47539257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  assert(DelayedDiagnostics.getCurrentPool());
475413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
47559257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  DelayedDiagnostics.popWithoutEmitting(state);
47569257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
47579257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // When delaying diagnostics to run in the context of a parsed
47589257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // declaration, we only want to actually emit anything if parsing
47599257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // succeeds.
47609257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  if (!decl) return;
47619257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
47629257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // We emit all the active diagnostics in this pool or any of its
47639257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // parents.  In general, we'll get one pool for the decl spec
47649257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // and a child pool for each declarator; in a decl group like:
47659257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  //   deprecated_typedef foo, *bar, baz();
47669257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // only the declarator pops will be passed decls.  This is correct;
47679257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // we really do need to consider delayed diagnostics from the decl spec
47689257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // for each of the different declarations.
476913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  const DelayedDiagnosticPool *pool = &poppedPool;
47709257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  do {
477113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    for (DelayedDiagnosticPool::pool_iterator
47729257664568bf375b7790131a84d9a4fa30a5b7e3John McCall           i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
47739257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      // This const_cast is a bit lame.  Really, Triggered should be mutable.
47749257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
4775eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
47762f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
47772f514480c448708ec382a684cf5e035d3a827ec8John McCall
4778eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
47792f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
4780e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        // Don't bother giving deprecation diagnostics if the decl is invalid.
4781e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        if (!decl->isInvalidDecl())
47829257664568bf375b7790131a84d9a4fa30a5b7e3John McCall          HandleDelayedDeprecationCheck(diag, decl);
47832f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
47842f514480c448708ec382a684cf5e035d3a827ec8John McCall
47852f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
47869257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        HandleDelayedAccessCheck(diag, decl);
47872f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
4788f85e193739c953358c865005855253af4f68a497John McCall
4789f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
47909257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        handleDelayedForbiddenType(*this, diag, decl);
4791f85e193739c953358c865005855253af4f68a497John McCall        break;
479254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
479354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
47949257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  } while ((pool = pool->getParent()));
47952f514480c448708ec382a684cf5e035d3a827ec8John McCall}
479658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
479713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// Given a set of delayed diagnostics, re-emit them as if they had
479813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// been delayed in the current context instead of in the given pool.
479913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// Essentially, this just moves them to the current pool.
480013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCallvoid Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
480113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
480213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  assert(curPool && "re-emitting in undelayed context not supported");
480313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  curPool->steal(pool);
48042f514480c448708ec382a684cf5e035d3a827ec8John McCall}
48052f514480c448708ec382a684cf5e035d3a827ec8John McCall
48062f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
48072f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
48080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
48092f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
4810c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    // A category implicitly has the availability of the interface.
4811c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4812c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis      return CatD->getClassInterface()->isDeprecated();
48132f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
48142f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
48152f514480c448708ec382a684cf5e035d3a827ec8John McCall}
48162f514480c448708ec382a684cf5e035d3a827ec8John McCall
4817c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedmanstatic void
4818c3b2308f66fe8abd2c1a911b500c0b989c295819Eli FriedmanDoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message,
4819c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman                         SourceLocation Loc,
4820c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman                         const ObjCInterfaceDecl *UnknownObjCClass) {
4821c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman  DeclarationName Name = D->getDeclName();
4822c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman  if (!Message.empty()) {
4823c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman    S.Diag(Loc, diag::warn_deprecated_message) << Name << Message;
4824c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman    S.Diag(D->getLocation(),
4825c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
4826c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman                                  : diag::note_previous_decl) << Name;
4827c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman  } else if (!UnknownObjCClass) {
4828c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman    S.Diag(Loc, diag::warn_deprecated) << D->getDeclName();
4829c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman    S.Diag(D->getLocation(),
4830c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
4831c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman                                  : diag::note_previous_decl) << Name;
4832c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman  } else {
4833c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman    S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name;
4834c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman    S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
4835c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman  }
4836c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman}
4837c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman
48389c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
48392f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
48402f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
48412f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
48422f514480c448708ec382a684cf5e035d3a827ec8John McCall
48432f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4844c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman  DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(),
4845c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman                           DD.getDeprecationMessage(), DD.Loc,
4846c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman                           DD.getUnknownObjCClass());
484754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
484854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
48495f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
48508e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
485189ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
485254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4853eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
485408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
4855b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              UnknownObjCClass,
4856b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              Message));
485754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
485854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
485954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
486054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
48613a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
486254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4863c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman  DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass);
486454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4865