SemaDeclAttr.cpp revision adc6cbf5b502f1b58078455ab4fca66c7daac239
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,
46f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor  ExpectedStruct
47883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall};
48883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall
49e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
52e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
5387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D,
54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
5687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
6087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
64bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
666217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
67755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
686217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
69d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
70183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
76d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
77a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
7887c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) {
7987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return getFunctionType(D, false) != NULL;
80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
82a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
84d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
8587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) {
8687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isFunction(D)|| isa<ObjCMethodDecl>(D);
87d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
9287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
9387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isFunctionOrMethod(D))
94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
9687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
10087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<BlockDecl>(D);
101620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
102620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
104711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
10587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) {
106f85e193739c953358c865005855253af4f68a497John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
10787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
10887c44604325578b8de07d768391c1c9432404f5aChandler Carruth         isa<ObjCPropertyDecl>(D);
109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
110711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
111d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
112d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
113620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
11487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) {
11587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
11672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
117620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
11887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
119d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
1213568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
123d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
125d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
12687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) {
12787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
12872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
12987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
130d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
13187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_size();
1323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1333568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
13587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
13672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
13787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
138d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
139bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
1413568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1423568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
14387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) {
14487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
1455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
14687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->getResultType();
1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
14987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) {
15087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D)) {
15172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
15387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
154db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
155d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
15687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    return cast<ObjCMethodDecl>(D)->isVariadic();
1573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
16087c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) {
16187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
16207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
16507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
167183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
168b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
171506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
172506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
175506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
182085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1836217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
184085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1876217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
189085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
191085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
192465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
197085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
198b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May
199b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
2001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth                                  unsigned int Num) {
2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (Attr.getNumArgs() != Num) {
2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    return false;
2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  }
2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  return true;
2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth}
2091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
210db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
211b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May
212b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                  unsigned int Num) {
215b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (Attr.getNumArgs() < Num) {
216db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
217db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return false;
218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  return true;
221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
223db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski///
224fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var
225fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable
226fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
22739997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) {
228fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (isa<FieldDecl>(D))
229fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return true;
23039997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const VarDecl *vd = dyn_cast<VarDecl>(D))
231fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
232fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
235fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
236b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool.
237b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) {
238b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = Exp->getType();
239b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return QT->isBooleanType() || QT->isIntegerType();
240b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
241b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
242aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
243aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// Check to see if the type is a smart pointer of some kind.  We assume
244aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// it's a smart pointer if it defines both operator-> and operator*.
24560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchinsstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
24660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
24760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
24860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (Res1.first == Res1.second)
24960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return false;
25060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
25160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
25260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
25360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (Res2.first == Res2.second)
25460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return false;
25560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
25660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  return true;
257aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins}
258aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type.
260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message.
261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise
262ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
263ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                       const AttributeList &Attr) {
26439997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
265fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
26639997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer    if (QT->isAnyPointerType())
267fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
268aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
26960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    if (const RecordType *RT = QT->getAs<RecordType>()) {
27060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // If it's an incomplete type, it could be a smart pointer; skip it.
27160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // (We don't want to force template instantiation if we can avoid it,
27260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      // since that would alter the order in which templates are instantiated.)
27360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      if (RT->isIncompleteType())
27460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins        return true;
27560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
27660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins      if (threadSafetyCheckIsSmartPointer(S, RT))
27760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins        return true;
27860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    }
279aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
280ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
281fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
282fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
283fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
284fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
285fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
286fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
287fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
288fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
289b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points
290b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit.
2917d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) {
2927d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const RecordType *RT = QT->getAs<RecordType>())
293b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return RT;
2947d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2957d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  // Now check if we point to record type.
2967d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const PointerType *PT = QT->getAs<PointerType>())
2977d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer    return PT->getPointeeType()->getAs<RecordType>();
2987d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2997d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  return 0;
300b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
301b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
302bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
303fad5de9d674521017460f8445e2f81e2a1086290Jordy Rosestatic bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
304fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                             CXXBasePath &Path, void *Unused) {
305bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  const RecordType *RT = Specifier->getType()->getAs<RecordType>();
306bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (RT->getDecl()->getAttr<LockableAttr>())
307bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    return true;
308bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  return false;
309bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins}
310bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
311bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
3123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType
313ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// resolves to a lockable object.
31483cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchinsstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
31583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins                                   QualType Ty) {
31683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  const RecordType *RT = getRecordType(Ty);
31783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins
31883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  // Warn if could not get record type for this argument.
319d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT) {
320ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
32183cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      << Attr.getName() << Ty.getAsString();
32283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
3233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
32460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
325634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  // Don't check for lockable if the class hasn't been defined yet.
326634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  if (RT->isIncompleteType())
32783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
32860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
32960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  // Allow smart pointers to be used as lockable objects.
33060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  // FIXME -- Check the type that the smart pointer points to.
33160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins  if (threadSafetyCheckIsSmartPointer(S, RT))
33260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins    return;
33360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins
334bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  // Check if the type is lockable.
335bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  RecordDecl *RD = RT->getDecl();
336bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (RD->getAttr<LockableAttr>())
33783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
338bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
339bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  // Else check if any base classes are lockable.
340bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
341bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    CXXBasePaths BPaths(false, false);
342bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths))
343bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins      return;
3443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
345bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins
346bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins  S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
347bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins    << Attr.getName() << Ty.getAsString();
3483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
350b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
351ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// from Sidx, resolve to a lockable object.
3523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with.
3533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function
3543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list.
355ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
3563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         const AttributeList &Attr,
3573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         SmallVectorImpl<Expr*> &Args,
358b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
359b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
3603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
361b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
3623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
363ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    if (ArgExp->isTypeDependent()) {
364ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // FIXME -- need to check this again on template instantiation
365ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      Args.push_back(ArgExp);
366ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      continue;
367ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    }
368b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
36979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
37079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      // Ignore empty strings without warnings
37179747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (StrLit->getLength() == 0)
37279747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        continue;
37379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
374ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // We allow constant strings to be used as a placeholder for expressions
375ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // that are not valid C++ syntax, but warn that they are ignored.
376ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
377ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins        Attr.getName();
378ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      continue;
379ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    }
380ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins
3813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
382b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
38379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // A pointer to member expression of the form  &MyClass::mu is treated
38479747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // specially -- we need to look at the type of the member.
38579747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
38679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (UOp->getOpcode() == UO_AddrOf)
38779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
38879747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins          if (DRE->getDecl()->isCXXInstanceMember())
38979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins            ArgTy = DRE->getDecl()->getType();
39079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
3913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
393b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
397b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
398b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
399b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
400b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
4013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
4023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
4033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
404b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
405b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
406ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins          continue;
407b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
4083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
409b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
410b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
411b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
41283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    checkForLockableRecord(S, D, Attr, ArgTy);
413b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
4143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
415b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
416b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
417b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
418e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
419e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
420e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
421e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
4223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
4233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
4243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
4253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
427fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
428fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
436b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
440ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
444768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
446768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
449db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
450b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
451db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
452db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
453b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
455db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
456db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
457db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
458db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
459b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
460db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
462db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
463ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
464db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
465db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
466ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  SmallVector<Expr*, 1> Args;
467ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // check that all arguments are lockable objects
468ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
469ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  unsigned Size = Args.size();
470ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size != 1)
471ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
472ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr *Arg = Args[0];
473b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
474db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
475768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
4763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 S.Context, Arg));
477db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
478768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
479db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
480db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
482fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
483fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
484fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
485fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
486fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
487fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
488fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4891748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
490fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
491fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
492fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
493fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
494fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
495fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
496fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
497768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
498fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
499768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
500fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
501fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
502fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
503fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
504fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
505fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
506fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
507fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
508fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
509b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
510fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
511fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
512fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
513fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
514fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
515768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
516fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
517fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
518fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
51971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D,
520ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                      const AttributeList &Attr) {
52171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  assert(!Attr.isInvalid());
52271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
52371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!checkAttributeNumArgs(S, Attr, 0))
52471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
52571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
52671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
52771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
52871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany      << Attr.getName() << ExpectedFunctionOrMethod;
52971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
53071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  }
53171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
53271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
53371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany                                                          S.Context));
53471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany}
53571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
537db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
538db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
539db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
540b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
541db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
542db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
543db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
544b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
545b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
546db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
547b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
549db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
550db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
551ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that this attribute only applies to lockable types.
552b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
553b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
554b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
555b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
556ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
557b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
558b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
559b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
560b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
561b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
563ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that all arguments are lockable objects.
564ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
5653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
566ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
567ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
568ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
5693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
571768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
5723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                    StartArg, Size));
573db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
574768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
5753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                   StartArg, Size));
576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
577db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
579b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
580db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
583db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
584b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
585b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
586db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
587db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
591b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
593ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
5943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
597db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
598768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
5993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
6003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
601db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
602768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
6033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        S.Context, StartArg,
6043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        Size));
605db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
606db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
607db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
608b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
609db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
610db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
611b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
612db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
613db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
614b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
615db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
616db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
617db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
620b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
621b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
622b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
623b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
624b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
625b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 2> Args;
627b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
628ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
6293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
633768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
6343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              S.Context,
63569f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                              Attr.getArg(0),
6363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              StartArg, Size));
637db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
638768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
63969f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           S.Context,
64069f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           Attr.getArg(0),
64169f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           StartArg, Size));
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
645b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
646db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
647db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
648b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
650db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
651b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
652db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
656db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
657b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
659ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
6603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
661ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
662ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
663ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
6643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
666768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
6673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            S.Context, StartArg,
6683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            Size));
669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
670768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
6713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         S.Context, StartArg,
6723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         Size));
673db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
674db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
675db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
676b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
677db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
678db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
679db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
680db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
681b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
682db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
683db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
684db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
685db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
686db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
687b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
689ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
6903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
693768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
6943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
695db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
696db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
697db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
698b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
699db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
700db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
701b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
702db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
7033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
704db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
705b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
706db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
707db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
708db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
709db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
710db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
7113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
712b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
713b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
7143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
715f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  SmallVector<Expr*, 1> Args;
716f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
717f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  unsigned Size = Args.size();
718f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  if (Size == 0)
719f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins    return;
7203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
721f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context,
722f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins                                                Args[0]));
723db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
724db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
725db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
726b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
727db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
728db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
729b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
730db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
731db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
732b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
733db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
734db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
735db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
736db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
737db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
738b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
7393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
740ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
7413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
742ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
743ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
744ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
7453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
746768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
7473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
748db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
749db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
750db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
7511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
7521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
75387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
754545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
755803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
756545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
7576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
758bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
7609cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7619cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
7629cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7639cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
7649cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
765f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
766e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    SourceLocation TemplateKWLoc;
767f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
768f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
7694ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
770e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id,
771e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                          false, false);
7724ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
7734ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
7744ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
7754ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
7769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
7779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
7781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
7799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
7801731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
7817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
7826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
7859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
7869ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
7879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
788ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
789a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
790bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
7929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
7936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
7981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
7996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
800bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
80187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
802768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
80387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
8046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
8056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
8066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
807803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
808fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
80908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
8106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
811768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
8126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
8133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
8146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
81787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
818768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
819c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
820c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
821c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
822c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
8231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
82496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
8251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
82696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
827bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
82863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
82987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
83063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
831768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
83263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
83363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
83463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8354ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
83663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
83763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8382f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
8392f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // The IBOutlet/IBOutletCollection attributes only apply to instance
8402f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // variables or properties of Objective-C classes.  The outlet must also
8412f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // have an object reference type.
8422f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
8432f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
8440bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
8452f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << VD->getType() << 0;
8462f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
8472f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
8482f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
8492f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
8502f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
851f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
8522f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << PD->getType() << 1;
8532f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
8542f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
8552f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
8562f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else {
8572f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
8582f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    return false;
8592f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
860f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
8612f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  return true;
8622f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek}
8632f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
86563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
8661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
86763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
8682f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8692f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
87063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
87163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8722f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
87396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
87496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
8751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
8761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
877857e918a8a40deb128840308a318bf623d68295fTed Kremenek
878857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
879a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
880857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
881857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
882857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
883857e918a8a40deb128840308a318bf623d68295fTed Kremenek
8842f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
885857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
8862f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
887a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
888a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
889f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian    II = &S.Context.Idents.get("NSObject");
8903a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
891b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
89287c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
893a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
894a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
895a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
896a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
897b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
898a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
899a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
900a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
901a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
902f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
903a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
904a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
905a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
906f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
907f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
908857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
909857e918a8a40deb128840308a318bf623d68295fTed Kremenek
910d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
91168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
91268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
91368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
91468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
91568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
91668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
91768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
91868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
91968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
92068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
92168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
92268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
92368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
92468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
925587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopesstatic void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
926587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
927587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    return;
928587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
929587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  // In C++ the implicit 'this' function parameter also counts, and they are
930587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  // counted from one.
931587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  bool HasImplicitThisParam = isInstanceMethod(D);
932587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
933587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
934587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  SmallVector<unsigned, 8> SizeArgs;
935587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
936587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  for (AttributeList::arg_iterator I = Attr.arg_begin(),
937587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes       E = Attr.arg_end(); I!=E; ++I) {
938587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    // The argument must be an integer constant expression.
939587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    Expr *Ex = *I;
940587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    llvm::APSInt ArgNum;
941587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
942587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
943587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
944587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      << "alloc_size" << Ex->getSourceRange();
945587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      return;
946587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
947587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
948587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    uint64_t x = ArgNum.getZExtValue();
949587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
950587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (x < 1 || x > NumArgs) {
951587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
952587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      << "alloc_size" << I.getArgNum() << Ex->getSourceRange();
953587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      return;
954587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
955587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
956587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    --x;
957587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (HasImplicitThisParam) {
958587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      if (x == 0) {
959587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        S.Diag(Attr.getLoc(),
960587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes               diag::err_attribute_invalid_implicit_this_argument)
961587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        << "alloc_size" << Ex->getSourceRange();
962587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes        return;
963587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      }
964587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      --x;
965587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
966587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
967587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    // check if the function argument is of an integer type
968587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
969587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (!T->isIntegerType()) {
970587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
971587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      << "alloc_size" << Ex->getSourceRange();
972587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      return;
973587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
974587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
975587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    // check if the argument is a duplicate
976587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    SmallVectorImpl<unsigned>::iterator Pos;
977587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    Pos = std::find(SizeArgs.begin(), SizeArgs.end(), x);
978587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    if (Pos != SizeArgs.end()) {
979587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      S.Diag(Attr.getLoc(), diag::err_attribute_argument_duplicate)
980587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      << "alloc_size" << I.getArgNum() << Ex->getSourceRange();
981587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes      return;
982587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    }
983587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
984587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    SizeArgs.push_back(x);
985587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  }
986587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
987587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  // check if the function returns a pointer
988587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  if (!getFunctionType(D)->getResultType()->isAnyPointerType()) {
989587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
990587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes    << "alloc_size" << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange();
991587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  }
992587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
993587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  unsigned size = SizeArgs.size();
994587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  unsigned* start = &SizeArgs[0];
995587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  llvm::array_pod_sort(start, start + size);
996587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  D->addAttr(::new (S.Context) AllocSizeAttr(Attr.getRange(), S.Context, start,
997587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes                                             size));
998587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes}
999587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes
10001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1001bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
1002bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
100387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
1004fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1005883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1006eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
1007eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
1008bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
100907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
101007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
101187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
101287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1013eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
1014eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
10155f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
1016bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1017eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
1018eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
1019bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1020bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1021eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
10227a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
1023eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
1024ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
1025ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
1026fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1027fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
1028eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
1029eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
1030bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1031eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1032bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1033eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
1034fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
103530bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
1036eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
1037eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
1038bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1039465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
104007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
104107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
104207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
104307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
104407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
104507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
104607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
104707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
104807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
1049eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
1050eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
105187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
1052d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
105368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
1054dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1055eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
1056c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
1057fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
10587fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
1059eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
1060bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1061eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
1062eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
1063bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1064bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
1065bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
10667fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
106787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
106887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
1069d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
1070dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
1071d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
107246bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
1073bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1074ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
107560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
107660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
107760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
107860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
107960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
10807fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
108160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
1082eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
10837fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
10847fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
10857fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
1086dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1087768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
1089eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
1090eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
10911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
1092dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
1093dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
1094dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
1095dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
1096dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
1097dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
10982a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
10992a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
1100dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1101dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
1102dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
1103dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
1104dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1105dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1106dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
1107cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
11082a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
11092a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
1110cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
1111dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
1112dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1113dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1114dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
11152a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
11162a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
1117cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
1118dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
1119dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1120dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1121dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
11222a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
11232a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
1124cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
1125dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
1126dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
1127dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
1128dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1129dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
11302a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
11312a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
11322a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
11332a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
1134dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1135dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
113687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
1137883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1138883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
1139dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1140dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1141dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
114207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
114307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
114487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
114587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1146dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
11475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
1148dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1149dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
1150dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
1151dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
1152dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
11535f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
1154dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
11552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
11562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1157dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
11587a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1159dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1160dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1161dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1162dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1163dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1164dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1165dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1166dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1167dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1168dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1169dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1170dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1171dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1172dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1173dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1174dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
117507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
117607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
117707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
117807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
117907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
118007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
118107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
118207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
118307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1184dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1185cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1186cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1187dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
118887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1189dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1190dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1191dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1192cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1193dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1194dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1195dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1196dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1197dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1198dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1199cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1200dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1201dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
12027a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1203dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1204dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1205dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1206dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1207dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1208dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1209dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1210dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1211dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1212dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1213dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1214dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1215dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1216dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1217cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
121887c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
121987c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1220cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1221cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1222cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1223cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1224cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1225cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1226cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1227dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1228dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1229dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1230dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1231dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1232dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1233dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1234dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1235dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1236dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1237cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1238cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1239cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1240cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1241dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1242cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
124387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1244cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1245dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1246dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1247332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1248332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1249332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1250332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1251332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1252332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1253332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1254332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1255332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1256332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1257332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1258332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1259332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1260332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1261332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1262332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1263332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
126411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
126511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
12661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
126711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
126811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
126911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
127011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
127111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
127211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
127387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1274332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1275883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1276332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1277332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1278332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
127987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1280332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
128111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
128211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
128311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
128411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
128511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
128611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
128711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
128811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
128911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
129011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
129187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
12927a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
12937a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1294332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
12957a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
129611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
129711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
129811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
129911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
130011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
130111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
130211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
130311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
130411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
130511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
130611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
130711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
130811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
130911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
131011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
131111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
131211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
131311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
131411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
131511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1316332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1317332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
131811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
131911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
132011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
132111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
132211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
132311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
132411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
132511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
13267a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
132711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
132811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
132911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
13305cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
133111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
133211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
133311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
133411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
133511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
133611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1337768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1338f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
133911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
134011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1341768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
134211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
134311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
13441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
13456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1346545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
13473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
13486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13517a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
13526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
13536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1354bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13555cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1356fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
13573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
13586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1360bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1361bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1362f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1363f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1364f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1365f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
13666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1367bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1368768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1369f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
13706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1372ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramerstatic void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1373ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  // Check the attribute arguments.
1374ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!checkAttributeNumArgs(S, Attr, 0))
1375ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1376ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1377ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!isa<FunctionDecl>(D)) {
1378ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1379ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << ExpectedFunction;
1380ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1381ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1382ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1383ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (D->hasAttr<HotAttr>()) {
1384ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1385ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << "hot";
1386ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1387ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1388ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1389ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context));
1390ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer}
1391ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1392ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramerstatic void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1393ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  // Check the attribute arguments.
1394ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!checkAttributeNumArgs(S, Attr, 0))
1395ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1396ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1397ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (!isa<FunctionDecl>(D)) {
1398ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1399ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << ExpectedFunction;
1400ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1401ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1402ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1403ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  if (D->hasAttr<ColdAttr>()) {
1404ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1405ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer      << Attr.getName() << "cold";
1406ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer    return;
1407ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  }
1408ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
1409ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context));
1410ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer}
1411ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer
14121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1413dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
14141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1415dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1416dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
141787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1418dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1419883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1420dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1421dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1422dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1423768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1424dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1425dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
14261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
14271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1428dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1429831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1431af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1432af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
14335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
143487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
14355bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1436883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
14375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
14385bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1439bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1440768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1441af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1442af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
14431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1444dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1445831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
144676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
144776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
144876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
14491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
145087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
14511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
14522cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1453768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
14542cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
14552cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1456fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1457fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
14582cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
145976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
146076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
14611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
146234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
14631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
146434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
146534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1466768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
146734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
146834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
14691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
147056aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
147187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1472768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1473722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1474722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1475883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1476a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1477a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
14781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
147956aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
148087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1481768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1482722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1483722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1484883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1485a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1486a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
14871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
148887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1489711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1490711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1491711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
149287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1493711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1494883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1495711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1496711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1497711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1498768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1499711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1500711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1501711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1502831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1503711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1504711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1505711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1506711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1507711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1508711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1509b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1510b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
15111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
15121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1513b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1514b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1515b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1516b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
15171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
15181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1519b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
152087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
152187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
15223ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
15233ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1524e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1525e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1526b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1527883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1528b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
152919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
15306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1531b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1532768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
15336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
153535cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
15361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
153735cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
153835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
153935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1540f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1541f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1542f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1543f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1544f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
154535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
154635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
154735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
154835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
154935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
155035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
155135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
155235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
155335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
155435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
155535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
155635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
155735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
155835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
155935cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
156087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
156135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1562883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
156335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
156435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
156535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
156687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
156735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
156835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
156935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
157035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
157187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
157201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
157301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
157401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
157501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
157601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
157701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
157801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
157901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
158001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
158101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
158201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
158301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1584f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1585f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
158601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
158701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
158801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
158901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
159001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
159101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
159201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1593768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
159435cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
159535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
15961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
159787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1598bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1599883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1600bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1601bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1602bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1603bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1604bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
16051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
160673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1607831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
16083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
160973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
161073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1611bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
161287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
1613568eae48a4e19c0359cdcd2a33b8ec9812e4abbcDaniel Jasper      !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) {
1614fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1615883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
161673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
161773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1618bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1619768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
162073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
162173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1622f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1623f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1624f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1625f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1626f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1627f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1628f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1629f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1630f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1631f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1632f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1633f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1634f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1635f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1636f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1637f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1638f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
16391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1640b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1641831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1642b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1643b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1644b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1645bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
164687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1647186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1648b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1649b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1650b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
165187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1652b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1653883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1654b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1655b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1656bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1657768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1658b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1659b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
16601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1662bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1663bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
16643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1665bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
16663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
16673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
16683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
16697a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
16703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1671ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1672ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1673fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
16743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
16753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
16763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
16773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
16783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1679bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
168087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1681fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1682883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
16833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
16843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
16853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1686768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1687f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
16883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
16893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
16901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1692bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1693bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
16943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1695bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
16963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
16973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
16983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
16997a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
17003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1701ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1702ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1703fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
17043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
17053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
17063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
17073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
17083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1709bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
171087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1711fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1712883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
17133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
17143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
17153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1716768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1717f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
17183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
17193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1720bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramertemplate <typename AttrTy>
1721bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramerstatic void handleAttrWithMessage(Sema &S, Decl *D, const AttributeList &Attr,
1722bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer                                  const char *Name) {
1723951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1724951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1725bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1726c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1727c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1728bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer
1729bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer  // Handle the case where the attribute has a text message.
17305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1731951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1732951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1733c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1734951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1735bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer        << Name;
1736c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1737c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1738951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
17396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1740bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1741bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer  D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str));
1742bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1743bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1744742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1745742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1746742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1747742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1748742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1749742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1750742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1751742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1752742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1753768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1754742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1755742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1756b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beardstatic void handleObjCRootClassAttr(Sema &S, Decl *D,
1757b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard                                    const AttributeList &Attr) {
1758b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (!isa<ObjCInterfaceDecl>(D)) {
1759b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1760b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1761b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1762b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1763b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  unsigned NumArgs = Attr.getNumArgs();
1764b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (NumArgs > 0) {
1765b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1766b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1767b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1768b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1769b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
1770b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard}
1771b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
177271207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
1773e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                            const AttributeList &Attr) {
1774341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  if (!isa<ObjCInterfaceDecl>(D)) {
1775341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
1776341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    return;
1777341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  }
1778341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian
1779e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1780e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  if (NumArgs > 0) {
1781e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1782e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    return;
1783e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  }
1784e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
178571207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
1786e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                 Attr.getRange(), S.Context));
1787e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian}
1788e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
1789fad5de9d674521017460f8445e2f81e2a1086290Jordy Rosestatic bool checkAvailabilityAttr(Sema &S, SourceRange Range,
1790fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  IdentifierInfo *Platform,
1791fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  VersionTuple Introduced,
1792fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  VersionTuple Deprecated,
1793fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose                                  VersionTuple Obsoleted) {
17945f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
17950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
17963b294360febd89e3383143af086efe2014571afaRafael Espindola  if (PlatformName.empty())
17970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
17980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1799c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
18000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
18013b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Introduced.empty() && !Deprecated.empty() &&
18023b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Introduced <= Deprecated)) {
18033b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
18043b294360febd89e3383143af086efe2014571afaRafael Espindola      << 1 << PlatformName << Deprecated.getAsString()
18053b294360febd89e3383143af086efe2014571afaRafael Espindola      << 0 << Introduced.getAsString();
18063b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
18070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
18080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
18093b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Introduced.empty() && !Obsoleted.empty() &&
18103b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Introduced <= Obsoleted)) {
18113b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
18123b294360febd89e3383143af086efe2014571afaRafael Espindola      << 2 << PlatformName << Obsoleted.getAsString()
18133b294360febd89e3383143af086efe2014571afaRafael Espindola      << 0 << Introduced.getAsString();
18143b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
18153b294360febd89e3383143af086efe2014571afaRafael Espindola  }
18163b294360febd89e3383143af086efe2014571afaRafael Espindola
18173b294360febd89e3383143af086efe2014571afaRafael Espindola  if (!Deprecated.empty() && !Obsoleted.empty() &&
18183b294360febd89e3383143af086efe2014571afaRafael Espindola      !(Deprecated <= Obsoleted)) {
18193b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
18203b294360febd89e3383143af086efe2014571afaRafael Espindola      << 2 << PlatformName << Obsoleted.getAsString()
18213b294360febd89e3383143af086efe2014571afaRafael Espindola      << 1 << Deprecated.getAsString();
18223b294360febd89e3383143af086efe2014571afaRafael Espindola    return true;
18233b294360febd89e3383143af086efe2014571afaRafael Espindola  }
18243b294360febd89e3383143af086efe2014571afaRafael Espindola
18253b294360febd89e3383143af086efe2014571afaRafael Espindola  return false;
18263b294360febd89e3383143af086efe2014571afaRafael Espindola}
18273b294360febd89e3383143af086efe2014571afaRafael Espindola
1828599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaAvailabilityAttr *Sema::mergeAvailabilityAttr(Decl *D, SourceRange Range,
1829599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              IdentifierInfo *Platform,
1830599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              VersionTuple Introduced,
1831599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              VersionTuple Deprecated,
1832599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              VersionTuple Obsoleted,
1833599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              bool IsUnavailable,
1834599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                              StringRef Message) {
183598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VersionTuple MergedIntroduced = Introduced;
183698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VersionTuple MergedDeprecated = Deprecated;
183798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VersionTuple MergedObsoleted = Obsoleted;
18383b294360febd89e3383143af086efe2014571afaRafael Espindola  bool FoundAny = false;
18393b294360febd89e3383143af086efe2014571afaRafael Espindola
184098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  if (D->hasAttrs()) {
184198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    AttrVec &Attrs = D->getAttrs();
184298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    for (unsigned i = 0, e = Attrs.size(); i != e;) {
184398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
184498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (!OldAA) {
184598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        ++i;
184698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
184798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
184898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
184998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      IdentifierInfo *OldPlatform = OldAA->getPlatform();
185098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (OldPlatform != Platform) {
185198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        ++i;
185298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
185398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
185498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
185598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      FoundAny = true;
185698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple OldIntroduced = OldAA->getIntroduced();
185798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple OldDeprecated = OldAA->getDeprecated();
185898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple OldObsoleted = OldAA->getObsoleted();
185998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      bool OldIsUnavailable = OldAA->getUnavailable();
186098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      StringRef OldMessage = OldAA->getMessage();
186198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
186298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if ((!OldIntroduced.empty() && !Introduced.empty() &&
186398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola           OldIntroduced != Introduced) ||
186498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (!OldDeprecated.empty() && !Deprecated.empty() &&
186598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola           OldDeprecated != Deprecated) ||
186698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (!OldObsoleted.empty() && !Obsoleted.empty() &&
186798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola           OldObsoleted != Obsoleted) ||
186898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (OldIsUnavailable != IsUnavailable) ||
186998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola          (OldMessage != Message)) {
187098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
187198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Diag(Range.getBegin(), diag::note_previous_attribute);
187298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Attrs.erase(Attrs.begin() + i);
187398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        --e;
187498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
187598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
187698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
187798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple MergedIntroduced2 = MergedIntroduced;
187898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple MergedDeprecated2 = MergedDeprecated;
187998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      VersionTuple MergedObsoleted2 = MergedObsoleted;
188098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
188198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (MergedIntroduced2.empty())
188298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        MergedIntroduced2 = OldIntroduced;
188398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (MergedDeprecated2.empty())
188498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        MergedDeprecated2 = OldDeprecated;
188598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (MergedObsoleted2.empty())
188698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        MergedObsoleted2 = OldObsoleted;
188798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
188898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
188998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola                                MergedIntroduced2, MergedDeprecated2,
189098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola                                MergedObsoleted2)) {
189198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        Attrs.erase(Attrs.begin() + i);
189298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        --e;
189398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola        continue;
189498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      }
189598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
189698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      MergedIntroduced = MergedIntroduced2;
189798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      MergedDeprecated = MergedDeprecated2;
189898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      MergedObsoleted = MergedObsoleted2;
189998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola      ++i;
190098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    }
19010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
19020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
19033b294360febd89e3383143af086efe2014571afaRafael Espindola  if (FoundAny &&
19043b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedIntroduced == Introduced &&
19053b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedDeprecated == Deprecated &&
19063b294360febd89e3383143af086efe2014571afaRafael Espindola      MergedObsoleted == Obsoleted)
1907599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return NULL;
19083b294360febd89e3383143af086efe2014571afaRafael Espindola
190998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
19103b294360febd89e3383143af086efe2014571afaRafael Espindola                             MergedDeprecated, MergedObsoleted)) {
1911599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return ::new (Context) AvailabilityAttr(Range, Context, Platform,
1912599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                            Introduced, Deprecated,
1913599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                            Obsoleted, IsUnavailable, Message);
19140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
1915599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return NULL;
19163b294360febd89e3383143af086efe2014571afaRafael Espindola}
19170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
19183b294360febd89e3383143af086efe2014571afaRafael Espindolastatic void handleAvailabilityAttr(Sema &S, Decl *D,
19193b294360febd89e3383143af086efe2014571afaRafael Espindola                                   const AttributeList &Attr) {
19203b294360febd89e3383143af086efe2014571afaRafael Espindola  IdentifierInfo *Platform = Attr.getParameterName();
19213b294360febd89e3383143af086efe2014571afaRafael Espindola  SourceLocation PlatformLoc = Attr.getParameterLoc();
19223b294360febd89e3383143af086efe2014571afaRafael Espindola
19233b294360febd89e3383143af086efe2014571afaRafael Espindola  if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty())
19243b294360febd89e3383143af086efe2014571afaRafael Espindola    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
19253b294360febd89e3383143af086efe2014571afaRafael Espindola      << Platform;
19263b294360febd89e3383143af086efe2014571afaRafael Espindola
19273b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
19283b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
19293b294360febd89e3383143af086efe2014571afaRafael Espindola  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
19303b294360febd89e3383143af086efe2014571afaRafael Espindola  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
1931006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  StringRef Str;
1932006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  const StringLiteral *SE =
1933006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
1934006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  if (SE)
1935006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    Str = SE->getString();
19363b294360febd89e3383143af086efe2014571afaRafael Espindola
1937599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(D, Attr.getRange(),
1938599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Platform,
1939599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Introduced.Version,
1940599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Deprecated.Version,
1941599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      Obsoleted.Version,
1942599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                                      IsUnavailable, Str);
1943599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
1944599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
194598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola}
194698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola
1947599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaVisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
1948599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                          VisibilityAttr::VisibilityType Vis) {
1949dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola  if (isa<TypedefNameDecl>(D)) {
1950dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "visibility";
1951599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return NULL;
1952dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola  }
195398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  VisibilityAttr *ExistingAttr = D->getAttr<VisibilityAttr>();
195498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  if (ExistingAttr) {
195598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    VisibilityAttr::VisibilityType ExistingVis = ExistingAttr->getVisibility();
195698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    if (ExistingVis == Vis)
1957599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola      return NULL;
195898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    Diag(ExistingAttr->getLocation(), diag::err_mismatched_visibility);
195998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    Diag(Range.getBegin(), diag::note_previous_attribute);
196098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    D->dropAttr<VisibilityAttr>();
196198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola  }
1962599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return ::new (Context) VisibilityAttr(Range, Context, Vis);
19630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
19640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
19651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
19666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
19671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
19686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1969bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19707a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
19716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
19726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1973bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19745cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1975fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
19763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
19776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1979bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1981cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1982bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1983c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1984cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1985c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1986cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1987c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1988cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
19894188760f6bb20f91c6883dffd89204419f852deeJohn McCall  else if (TypeStr == "protected") {
19904188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // Complain about attempts to use protected visibility on targets
19914188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // (like Darwin) that don't support it.
19924188760f6bb20f91c6883dffd89204419f852deeJohn McCall    if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
19934188760f6bb20f91c6883dffd89204419f852deeJohn McCall      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
19944188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Default;
19954188760f6bb20f91c6883dffd89204419f852deeJohn McCall    } else {
19964188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Protected;
19974188760f6bb20f91c6883dffd89204419f852deeJohn McCall    }
19984188760f6bb20f91c6883dffd89204419f852deeJohn McCall  } else {
199908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
20006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2002bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2003599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type);
2004599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
2005599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
20066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
20091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
2010d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
2011d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
201287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
2013883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
2014d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
2015d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
2016d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
201787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
201887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
201987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2020d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
2021d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
202287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2023d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
202487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2025d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
2026d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
2027d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
20285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
2029d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
2030d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
2031d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
2032d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
2033d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
2034d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
2035d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
2036d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
2037d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
2038d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
2039d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
2040d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
2041d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
2042d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
2043d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
2044d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
204587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
2046d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
2047d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
2048d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
2049f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
2050f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
2051f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
2052f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
2053f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
2054f85e193739c953358c865005855253af4f68a497John McCall    return;
2055f85e193739c953358c865005855253af4f68a497John McCall  }
2056f85e193739c953358c865005855253af4f68a497John McCall
2057768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
2058f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
2059d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
2060d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
20611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
20621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
20631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
20640db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
2065bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20660db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
20670db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
20680db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
20690db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
20700db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
2071bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2072768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
20730db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
20740db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
20751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
2076fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
20772b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2078fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
2079fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
2080162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2081fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
2082fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
20836217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
2084fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2085fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
2086fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
2087fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
20883427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
20893427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian    QualType T = PD->getType();
20903427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian    if (!T->isPointerType() ||
20913427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
20923427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian      S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
20933427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian      return;
20943427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian    }
20953427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian  }
20963427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian  else {
2097f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // It is okay to include this attribute on properties, e.g.:
2098f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
2099f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2100f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
2101f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // In this case it follows tradition and suppresses an error in the above
2102f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // case.
21039b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
2104f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  }
2105768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
2106fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
2107fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
2108bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
21091b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2110f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
21112b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2112f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
2113f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
2114f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
2115f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
2116f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
2117f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
2118f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
2119f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
2120768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
2121f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
2122f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
21231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2124bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2125fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
21263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
21279eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
21289eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2129bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21309eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
21313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
21329eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
21339eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2135cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
213692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
21379eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
21389eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
2139fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
21403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
21419eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
21429eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
2143bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2144768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
21459eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
21469eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
21471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2148770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
2149770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
2150bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
2151770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
2152bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21543323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
2155770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
21567a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
2157770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
2158ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2159ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
2160fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
21613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
2162770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2163770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2164bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21653323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
2166fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2167fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
2168770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2169770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
21703323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
21713323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
2172770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2173770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
21743323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
2175770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
21767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
2177770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
2178ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2179ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
2180fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
21813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
2182770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2183770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2184770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
2185bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21863323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
2187770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
2188770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
2189fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2190fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
2191770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2192770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
2193770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2194770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
219587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
21963323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
2197897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
2198897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
2199897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
2200897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
2201bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2202897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
22033bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2204770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
2205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
220687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
2207770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
22083bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2209770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
22102f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
2211a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
2212a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    if (!BD->isVariadic()) {
2213a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2214a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      return;
2215a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    }
221687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
22172f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
2218daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
221987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
2220f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
22212f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
22223bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
22233bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
22242f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
22252f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
2226ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
22272f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2228883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
22292f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
22302f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
2231770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
2232fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2233883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
2234770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
2235770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
2236768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
2237f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
2238770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
2239770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
22401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
2241026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
22421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2243026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
2244026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
2245f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
2246026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2247883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
2248026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
2249026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
2250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2251f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
2252f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2253f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
2254f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
2255f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
2256f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2257f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
2258f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2259f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
2260f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
2261f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
2262f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
2263768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
2264026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
2265026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
22661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
22676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
226887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
226987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
22706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
22716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
22726e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
227387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
227413c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    if (isa<CXXRecordDecl>(D)) {
227513c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
227613c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      return;
227713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    }
227887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
227987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
2280f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
2281f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
2282f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
228387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
2284332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
2285332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
2286332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
228787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
22886e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
22896e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
2290bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2291768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
22926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
22936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
22956e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
22961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
22976e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
22981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
22996e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
23006e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
23016e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
23020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
23030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
23040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
23050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
23060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
2307def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2308bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
230990eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2310def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
2311def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
2312c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2313883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
23146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
23156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
23166e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
23176e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
2318768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
23196e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
23206e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
23211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
23221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
23236f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
23241731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
23256f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
23266f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
23276f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
23286f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
23297a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
23306f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
2331ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2332ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
23336f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
23346f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
23356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
23366f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
23376f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
23386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
2339768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
2340cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
23416f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
23426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
23436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
2344599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaSectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
2345599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                    StringRef Name) {
2346420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola  if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
2347420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola    if (ExistingAttr->getName() == Name)
2348599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola      return NULL;
2349420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola    Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section);
2350420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola    Diag(Range.getBegin(), diag::note_previous_attribute);
2351599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    return NULL;
2352420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola  }
2353599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return ::new (Context) SectionAttr(Range, Context, Name);
2354420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola}
2355420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola
23561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
235717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
23581731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
235917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
236017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
236117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
236217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
23637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2364797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
236517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
2366797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
236717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
236817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
23691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2370797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
2371bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2372a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2373a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2374a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2375797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2376797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
23771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2378a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2379a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2380a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2381a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2382a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2383599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(),
2384599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                            SE->getString());
2385599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
2386599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
238717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
238817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
23896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
23916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2392831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
23933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
23946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2396b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
239787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2398b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2399ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2400b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2401768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2402b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
24036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
24046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2406232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2407831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
24083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2409232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2410232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
241287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2413b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2414ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2415b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2416768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2417b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2418232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2419232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
24201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2421232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
24221731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2423232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2424bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2425768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2426232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2427232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
24281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2429bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2430f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2431f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2432f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2433bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2434f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2435f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2436f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2437f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2438bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
243987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2440bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2441f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2442f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2443f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2444f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2445bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2446f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2447c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2448f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2449f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2450f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2451f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2452f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2453f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2454f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2455f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2456bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2457f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2458f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2459f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2460f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2461f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2462f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2463f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2464f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2465f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2466f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2467f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2468f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2469f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2470f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2471bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
247289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
247389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
247489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
247589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2476b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2477b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2478f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
247989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
248089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
248189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
248289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2483bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2484768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
24855f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
2486f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2487f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2488bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
24901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
24911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
24925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
24931731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
249487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
24955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2496883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
24975b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
24985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
249907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
250007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
250107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
250287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
250387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
25045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
250507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
25065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
25077a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
25085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2509ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2510ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
25115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
25125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
25135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
25145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2515bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
25175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
25185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
25195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
25205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2521bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2523bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
252407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
252507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
252607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
252707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
252807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
252907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
253007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
253107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
253207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
25335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
253487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2535bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
25375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
25385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
25395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
25406217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
25415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
25425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2543bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
25445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
25455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2546bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
254787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
25485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
25495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
25505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
25516217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
25525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
25535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2554bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
25555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
25565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2557bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2558bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2559768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
256007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
25615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
25625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
25632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
25642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
25652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
25662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
25672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
25683c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
25692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
25702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
25712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
25722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
25732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
25745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
2575c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer  return llvm::StringSwitch<FormatAttrKind>(Format)
2576c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    // Check for formats that get handled specially.
2577c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("NSString", NSStringFormat)
2578c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("CFString", CFStringFormat)
2579c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("strftime", StrftimeFormat)
2580c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer
2581c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    // Otherwise, check for supported formats.
2582c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
2583c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
2584c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Case("kprintf", SupportedFormat) // OpenBSD.
2585c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer
2586c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
2587c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer    .Default(InvalidFormat);
25882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
25892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2590521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2591521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
25921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
25931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
25944e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!S.getLangOpts().CPlusPlus) {
2595521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2596521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2597521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2598521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
259987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2600b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2601b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2602b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2603b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
260487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2605b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2606b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2607b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2608b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2609b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2610b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2611b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2612b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2613521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2614521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2615521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2616521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2617521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
26187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2619b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2620521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2621521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2622521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2623521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2624521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2625521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2626521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2627521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
26289f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2629521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2630521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2631521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2632521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2633521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2634521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2635768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2636f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2637521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2638521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2639599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaFormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
2640599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                  int FormatIdx, int FirstArg) {
2641bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola  // Check whether we already have an equivalent format attribute.
2642bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola  for (specific_attr_iterator<FormatAttr>
2643bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola         i = D->specific_attr_begin<FormatAttr>(),
2644bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola         e = D->specific_attr_end<FormatAttr>();
2645bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola       i != e ; ++i) {
2646bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola    FormatAttr *f = *i;
2647bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola    if (f->getType() == Format &&
2648bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola        f->getFormatIdx() == FormatIdx &&
2649bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola        f->getFirstArg() == FirstArg) {
2650bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola      // If we don't have a valid location for this attribute, adopt the
2651bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola      // location.
2652bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola      if (f->getLocation().isInvalid())
2653bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola        f->setRange(Range);
2654599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola      return NULL;
2655bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola    }
2656bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola  }
2657bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola
2658599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
2659599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                    FirstArg);
2660bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola}
2661bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola
2662bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2663bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
26641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
26656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2666545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2667fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
26683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
26696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
26716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2672545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
26733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
26746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
26766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
267787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2678fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2679883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
26806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
26826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
268307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
268407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
268587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
268687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
26876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
26886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
26906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
26922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
26932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
26942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
26952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
26962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
26973c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
26983c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
26993c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
27003c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
27012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2702fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
270301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
27046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
27056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
27066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
27087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2709803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2710ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2711ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2712fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
27133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
27146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
27156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
27166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2718fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
27193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
27206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
27216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
27226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
27246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2725bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
27264a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
27274a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
272807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
272907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
273007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
27314a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
27324a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
27334a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
27344a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
27351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
27366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
273787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
27386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2740085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2741fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2742fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2743085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2744085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
27452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2746390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2747390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2748803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2749390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2750fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2751fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
27526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2753bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
27546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
27556217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2756390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2757fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2758fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
27596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
27606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
27616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
27637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2764803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2765ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2766ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2767fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
27683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
27696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
27706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
27716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
27736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
277487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
27756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
27766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
277787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
27786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
27796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
27806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
27816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
27833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
27842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
27856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2786fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2787fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
27886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
27896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
27906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
27916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2792fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
27933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
27946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
27956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
27966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2797599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format,
2798599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                          Idx.getZExtValue(),
2799599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola                                          FirstArg.getZExtValue());
2800599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola  if (NewAttr)
2801599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola    D->addAttr(NewAttr);
28026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
28036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
28051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
28066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
28071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
28106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
28120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
281387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
28140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
28150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
28160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
281787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
28180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
28190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2820fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2821883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
28226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
28246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28255e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall  if (!RD->isCompleteDefinition()) {
2826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
28270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
28280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
28290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
28300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
283117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
283217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
28330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
28340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
28350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
28360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2837bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
2838581deb3da481053c4993c7600f97acf7768caac5David Blaikie  FieldDecl *FirstField = *Field;
28390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
284090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2841bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
284290cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
284390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
28440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
28450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2846bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
28470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
28480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
28490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
28500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
28510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
28520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
28530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
28540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2855bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
28560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2857bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
28580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
28590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
28600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2861bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
28620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
28630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2864bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2865bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2866bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
28676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2868768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
28696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
28706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
28726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
28731731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
28746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28751731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
28767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2877797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2878bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
28796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
28806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
28816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2882797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
28836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
28846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
288577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
288677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
288777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
288877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
288977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
289077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
289177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
289277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
2893768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
2894f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
28956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
28966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
28986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2899545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
29003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
29016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2903bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2904bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2905bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2906bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
29076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2908545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2909768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0));
29104ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
29114ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
29124ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2913768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0));
29144ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
29154ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2916768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
29170b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  // FIXME: Handle pack-expansions here.
29180b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  if (DiagnoseUnexpandedParameterPack(E))
29190b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne    return;
29200b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne
29214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
29224ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2923768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
29246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
29256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2926bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2927768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
2928cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
292949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
2930ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor  ExprResult ICE
2931ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor    = VerifyIntegerConstantExpression(E, &Alignment,
2932ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor        diag::err_aligned_attribute_argument_not_int,
2933ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor        /*AllowFold*/ false);
2934282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  if (ICE.isInvalid())
293549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
2936396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
29374ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
29384ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2939396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2940396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2941396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2942282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take()));
2943cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2944cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2945768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
2946cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2947cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2948768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS));
2949cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
29506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2951fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2952d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2953bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2954fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2955bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2956bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2957bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
29581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2959fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2960fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2961fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2962fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
29631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2964fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
29651731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2966fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2967fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2968fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
29690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2970fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2971fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2972210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
29735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2974fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2975fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2976210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2977210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2978fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2979fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2980fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
298173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2982210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2983fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
298473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
298573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
298673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
298773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
298873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
298973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
299073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
299173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
299273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
299373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
299473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
299573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
299673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
299773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
299873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
299973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
3000fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3001fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
3002fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
3003fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
3004210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
3005bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3006210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
3007bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
3008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3009fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
3010210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
3011bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3012fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3013fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3014fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3015fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
3016162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
3017fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
3018fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
3019fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
3020fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
3021fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
3022768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
3023fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3024fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
302573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
3026183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
302773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
302873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
30292ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
303073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
303173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
303273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
303373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
303473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
303573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
303673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
303773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
303873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
3039390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
3040390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
3041390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
3042390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
3043f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
3044f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
3045fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
3046fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
3047fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
30483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
3049fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3050fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
30513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3052fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
3053fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
305473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
305573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
305673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
305773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
3058fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
30590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
3060fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
30610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
3062fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3063fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
306473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
306573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
306673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
306773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
3068fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
30690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
3070fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
30710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
3072fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3073fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
3074fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
30750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
3076fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
30770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
3078fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
30790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
3080fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
3081fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
3082fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
30830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
3084fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
3085bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
3086aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
3087aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
3088aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
3089fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
3090bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
3091aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
3092aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
3093aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
3094fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
309573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
309673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
309773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
3098f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
3099f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
3100f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3101f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
3102f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
3103f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
3104f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
3105f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
3106f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
310773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
3108fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3109fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
311073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
311173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
3112fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
3113fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
3114fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
3115162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
3116ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
3117a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
3118ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
3119fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
3120fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
31210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
31221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3123d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
31241731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
3125d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
3126e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
312787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
3128d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3129883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
3130d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
3131d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
3132bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3133768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
3134d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
3135d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
31361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
31375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
31381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
31395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
31401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3141bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
314287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
31435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3144883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
31455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
31465bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
3147bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3148768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
31495bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
31505bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
31511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
31521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
31537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
31541731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
31557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
31561731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
31577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
315887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
31597255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3160883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
31617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
31627255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
31637255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
3164768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
3165f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
31667255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
31677255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
31681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3169ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3170ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
3171831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
3172ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3173ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3174ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3175ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
317687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
3177ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3178883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
3179ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3180ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3181ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3182768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
3183ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3184ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
3185ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3186ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3187ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
31881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3189ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3190ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
3191ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
3192ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3193ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3194ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3195ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
319687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
3197ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3198883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
3199ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3200ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3201ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3202768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
3203ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3204ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
3205ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3206ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3207ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
32081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3209ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3210ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
32111731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3212ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3213ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
321487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
3215ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3216883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
3217ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3218ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3219ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
322087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
32212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
3222723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
32232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
32242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
32252c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
32262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
32272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
32282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
32292c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
32302c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
32312c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
32322c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
32332c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
32342c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
3235768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
3236ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3237ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
3238ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3239ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3240ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
32411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3242ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3243ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
32441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3245ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
32461731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3247ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
324887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
3249ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3250883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
3251ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3252ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3253ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3254768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
3255ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3256ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
3257ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3258ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3259ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
32601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3261ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
3262ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
32631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
3264ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
32651731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3266ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
326787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
3268ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3269883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
3270ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
3271ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3272ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3273768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
3274ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3275ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
3276ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3277ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3278ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
32791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
328026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
32811731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
328226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
3283bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
328487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
3285c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
328626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3287883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
328826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
328926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
3290bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
32910130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
3292cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
3293c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
3294c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
3295bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3296768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
329726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
329826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
32991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
330087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3301711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
330287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
3303e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
330587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
3306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3307e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
330887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
330987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
331087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3311711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3312711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3313711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
331487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3315e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
3316768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
3317e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3318e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
3319768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
3320e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3321f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
3322768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
332304633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
3324e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
3325768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
3326e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
332752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3328768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
332952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
3330414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
333187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
3332414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
33335cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
333487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3335414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
333687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3337414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3338414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3339414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
33405f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3341414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
3342414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
3343414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
3344414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
3345414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
3346414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
334787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
334887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3349414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3350414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3351414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
3352768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
3353414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3354e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
3355e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
3356e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
3357e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
3358e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
33591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
336056aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
3361768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3362f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
3363f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
3364711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
3365711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
3366711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3367711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3368831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
3369831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
3370831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
3371711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3372711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
3373711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3374ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
337555d3aaf9a537888734762170823daf750ea9036dEli Friedman
3376414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3377414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3378711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
3379711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
3380711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
3381711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
3382711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
3383711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
3384414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
3385414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3386414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
33875cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3388414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3389414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3390414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3391414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3392414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3393414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
33945f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3395414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3396414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3397414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3398414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3399414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3400414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3401414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3402414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3403414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
34047530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("unexpected attribute kind");
3405711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3406711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3407711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3408711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3409711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
34101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
341187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3412711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3413711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
341487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3415711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3416711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
341787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
341887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
341987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3420ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3421ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
342255d3aaf9a537888734762170823daf750ea9036dEli Friedman
3423768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3424711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3425711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3426711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3427711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
342887c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
342987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3430711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3431711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
343287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
343387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
343487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3435711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3436711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3437711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
343887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
343955d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3440ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3441711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
344287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
344355d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
344487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3445711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
344655d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
344755d3aaf9a537888734762170823daf750ea9036dEli Friedman
3448bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
344987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
345055d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
345187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3452711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
345355d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
345455d3aaf9a537888734762170823daf750ea9036dEli Friedman
3455711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3456bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
345787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3458bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
345987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3460711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
346155d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
346255d3aaf9a537888734762170823daf750ea9036dEli Friedman
3463711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3464ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3465ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
34661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
34677b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
34687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
34697b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3470bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3471bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
34727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
34737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
34747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
347587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
34767b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3477883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
34787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
34797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
34807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
34817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
34827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
34837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
34847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
34857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
34867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
34877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
34887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
34897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
34907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
34917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
34927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
34937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
34947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
34957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
34967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
34977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
34987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
34997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
35007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
35017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
35027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3503768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
35047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
35057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
35067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
35077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
35087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
35097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
35107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
35110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3512b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3513b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3514b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3515c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
35166c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
35176c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isObjCObjectPointerType() ||
35186c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         S.Context.isObjCNSObjectType(type);
3519c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3520c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
35216c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
35226c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isPointerType() ||
35236c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         isValidSubjectOfNSAttribute(S, type);
3524c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3525c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
35261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
352787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3528c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
352987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3530768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3531c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3532c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3533c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3534c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
353587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3536c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3537c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3538c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3539c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3540c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3541c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3542c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3543c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
354487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3545768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3546c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3547c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3548c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3549c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3550768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3551c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3552768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3553c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3554c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
35551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
35561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
355787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
355887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3559768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3560c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3561c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3562c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3563768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3564c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3565c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
35661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
35671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3568b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3569c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3570bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
357187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3572c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
357387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3574831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
35754e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
357687c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3577f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
357887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3579c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
35805dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
358187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3582768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3583883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3584b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3585b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3586bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3587c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3588c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
358987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
35907530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("invalid ownership attribute");
3591c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3592c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3593c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3594c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3595c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3596c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3597c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3598c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3599c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3600c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3601c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3602c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3603c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3604c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3605c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
360687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3607768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3608bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
36095dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3610bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
361187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3612b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3613b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
3614c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
3615768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3616c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3617c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
361831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
3619768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3620f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
362131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
362231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
3623768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3624f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
362531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3626b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
3627768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3628f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3629b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3630b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
3631768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3632f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3633b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3634b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3635b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3636b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3637dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3638dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3639dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3640dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3641dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3642dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
364394d55d7ecdd693788a8f3910a0da1b5ecdaa8a86Fariborz Jahanian  if (!method) {
36440e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3645f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
3646dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3647dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3648dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3649dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3650dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3651f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian
3652f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3653f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3654dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3655dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3656dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3657dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3658dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3659dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3660dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3661dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3662dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3663768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3664dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3665dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
36668dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
36678dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
36688dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
36698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3670f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << A.getRange() << A.getName() << ExpectedFunction;
36718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
36728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
36738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
36748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer);
36758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
36768dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
36778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
36788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
36798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
36808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
36818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
36828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
36838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
36848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
36858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
36868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
36878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
36888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
36898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
36908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
36918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
36928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
36938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
36948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
36958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
36968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
36978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
36988dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
36998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
37008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3701fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
3702fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
3703fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
3704fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
3705fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3706f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedStruct;
3707fe98da0fa352462c02db037360788748f95466f7John McCall  }
3708fe98da0fa352462c02db037360788748f95466f7John McCall
3709fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
3710fe98da0fa352462c02db037360788748f95466f7John McCall
3711fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
3712fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
3713fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
37144e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (ParmName && S.getLangOpts().ObjC1) {
3715fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
3716fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
3717fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
3718fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
3719fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
3720fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
3721fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
3722fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
3723fe98da0fa352462c02db037360788748f95466f7John McCall      }
3724fe98da0fa352462c02db037360788748f95466f7John McCall    }
3725fe98da0fa352462c02db037360788748f95466f7John McCall  }
3726fe98da0fa352462c02db037360788748f95466f7John McCall
3727fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
3728fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
3729fe98da0fa352462c02db037360788748f95466f7John McCall}
3730fe98da0fa352462c02db037360788748f95466f7John McCall
37311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
37321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
373387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3734f85e193739c953358c865005855253af4f68a497John McCall
373587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3736f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    << Attr.getRange() << Attr.getName() << ExpectedVariable;
3737f85e193739c953358c865005855253af4f68a497John McCall}
3738f85e193739c953358c865005855253af4f68a497John McCall
37391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
37401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
374187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
374287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3743f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedVariable;
3744f85e193739c953358c865005855253af4f68a497John McCall    return;
3745f85e193739c953358c865005855253af4f68a497John McCall  }
3746f85e193739c953358c865005855253af4f68a497John McCall
374787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3748f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3749f85e193739c953358c865005855253af4f68a497John McCall
3750f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3751f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
375287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3753f85e193739c953358c865005855253af4f68a497John McCall      << type;
3754f85e193739c953358c865005855253af4f68a497John McCall    return;
3755f85e193739c953358c865005855253af4f68a497John McCall  }
3756f85e193739c953358c865005855253af4f68a497John McCall
3757f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3758f85e193739c953358c865005855253af4f68a497John McCall
3759f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3760f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3761f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3762f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3763f85e193739c953358c865005855253af4f68a497John McCall
3764f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3765f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3766f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3767f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3768f85e193739c953358c865005855253af4f68a497John McCall    break;
3769f85e193739c953358c865005855253af4f68a497John McCall
3770f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3771f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3772f85e193739c953358c865005855253af4f68a497John McCall    break;
3773f85e193739c953358c865005855253af4f68a497John McCall
3774f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3775f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
377687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3777f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3778f85e193739c953358c865005855253af4f68a497John McCall    break;
3779f85e193739c953358c865005855253af4f68a497John McCall  }
3780f85e193739c953358c865005855253af4f68a497John McCall
378187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3782768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3783f85e193739c953358c865005855253af4f68a497John McCall}
3784f85e193739c953358c865005855253af4f68a497John McCall
3785f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
37869428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  switch (Attr.getKind()) {
37879428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  default:
37889428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return false;
37899428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllimport:
37909428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllexport:
37919428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_uuid:
37929428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_deprecated:
37939428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noreturn:
37949428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_nothrow:
37959428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_naked:
37969428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noinline:
37979428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return true;
37989428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  }
379911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
380011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
380111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
380211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
380311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
380411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
38051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
380662ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
380711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
38081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
380911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
38101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
381111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
381211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
38135cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3814d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3815d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3816d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3817d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3818d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
38195f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3820d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3821d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3822d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3823f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
3824d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3825d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3826d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3827d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3828d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3829d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3830d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3831d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3832d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3833d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3834f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3835d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
38365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3837f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3838f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3839f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3840f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3841d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3842d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3843d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3844d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3845d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3846d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3847d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3848d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3849d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3850d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3851d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
385211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
3853768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
385411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3855d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
385611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3857f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3858f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3859c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallstatic void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3860c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  if (S.LangOpts.MicrosoftExt) {
3861c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    AttributeList::Kind Kind = Attr.getKind();
3862c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    if (Kind == AttributeList::AT_single_inheritance)
3863c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
3864c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context));
3865c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    else if (Kind == AttributeList::AT_multiple_inheritance)
3866c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
3867c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context));
3868c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    else if (Kind == AttributeList::AT_virtual_inheritance)
3869c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
3870c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context));
3871c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  } else
3872c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
3873c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall}
3874c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
3875c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallstatic void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3876c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  if (S.LangOpts.MicrosoftExt) {
3877c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    AttributeList::Kind Kind = Attr.getKind();
3878c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    if (Kind == AttributeList::AT_ptr32)
3879c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
3880c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context));
3881c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    else if (Kind == AttributeList::AT_ptr64)
3882c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
3883c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context));
3884c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    else if (Kind == AttributeList::AT_w64)
3885c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      D->addAttr(
3886c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall          ::new (S.Context) Win64Attr(Attr.getRange(), S.Context));
3887c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  } else
3888c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
3889c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall}
3890c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
3891adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencerstatic void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3892adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer  if (S.LangOpts.MicrosoftExt)
3893adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    D->addAttr(::new (S.Context) ForceInlineAttr(Attr.getRange(), S.Context));
3894adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer  else
3895adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
3896adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer}
3897adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer
3898b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
38990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
39000744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
39010744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
39021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
39031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
390460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
39051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
39061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
39071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
390860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
390960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
391060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
391160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3912e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
39131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
39141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3915803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
3916e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_ibaction:            handleIBAction(S, D, Attr); break;
3917e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutlet:          handleIBOutlet(S, D, Attr); break;
3918e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutletcollection:
39191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3920803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3921207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3922ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
39236e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
39244211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
39254211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3926bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3928803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
392960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
393060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
393160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
393260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
393360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
393460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
39351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
39361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3937587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes  case AttributeList::AT_alloc_size:  handleAllocSizeAttr   (S, D, Attr); break;
3938bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
39391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3940b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
39411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
39421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
39431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3944bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
39451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
39461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
39471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
39481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
3949bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer  case AttributeList::AT_deprecated:
3950bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    handleAttrWithMessage<DeprecatedAttr>(S, D, Attr, "deprecated");
3951bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    break;
39521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
39533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
39541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
39553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
39561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
39571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
39581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
39591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
39607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
39611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
39627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
39631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
39641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
39651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
39661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
39671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3968dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3969dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3970dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
39711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
3972ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  case AttributeList::AT_cold:        handleColdAttr        (S, D, Attr); break;
3973ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer  case AttributeList::AT_hot:         handleHotAttr         (S, D, Attr); break;
39741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
39751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
39761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
39771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
39781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3979b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3980b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
39811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3982f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
39831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3984f85e193739c953358c865005855253af4f68a497John McCall
3985dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3986dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3987dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3988fe98da0fa352462c02db037360788748f95466f7John McCall  case AttributeList::AT_ns_bridged:
3989fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
3990fe98da0fa352462c02db037360788748f95466f7John McCall
39918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_audited_transfer:
39928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_unknown_transfer:
39938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
39948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3995b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3996c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
39971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3998c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
39991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
4000c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
4001c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
400231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
400331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
4004b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
4005b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
40061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
4007b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
4008e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_reqd_work_group_size:
40091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
40106f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
4011521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
40121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
4013521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
40141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
40151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
4016bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer  case AttributeList::AT_unavailable:
4017bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    handleAttrWithMessage<UnavailableAttr>(S, D, Attr, "unavailable");
4018bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer    break;
4019e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_objc_arc_weak_reference_unavailable:
4020742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
4021742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
4022b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  case AttributeList::AT_objc_root_class:
4023b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    handleObjCRootClassAttr(S, D, Attr);
4024b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    break;
402571207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  case AttributeList::AT_objc_requires_property_definitions:
402671207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
4027e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    break;
40281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
4029f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  case AttributeList::AT_returns_twice:
4030f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
4031f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
40321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
40331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
40341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
4035026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
40361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
40371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
40381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
4039803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
40401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
4041803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
40420db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
40431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
40440db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
4045d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
40461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
4047d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
4048e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_NSObject:    handleObjCNSObject    (S, D, Attr); break;
40491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
40501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
40511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
40521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
40531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
40541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
40551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
40561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
4057bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
405805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
405905f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
40607255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
40611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
40627255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
406304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
406404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
406504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
4066f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
406752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
4068414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
40691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
407004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
4071f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
40721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
4073f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
4074c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
4075c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  // Microsoft attributes:
4076c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  case AttributeList::AT_ms_struct:
4077c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    handleMsStructAttr(S, D, Attr);
4078c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    break;
407911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
40801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
408111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
4082c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  case AttributeList::AT_single_inheritance:
4083c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  case AttributeList::AT_multiple_inheritance:
4084c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  case AttributeList::AT_virtual_inheritance:
4085c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    handleInheritanceAttr(S, D, Attr);
4086c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    break;
4087c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  case AttributeList::AT_w64:
4088c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  case AttributeList::AT_ptr32:
4089c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  case AttributeList::AT_ptr64:
4090c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    handlePortabilityAttr(S, D, Attr);
4091c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    break;
4092adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer  case AttributeList::AT_forceinline:
4093adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    handleForceInlineAttr(S, D, Attr);
4094adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer    break;
4095fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4096fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
4097fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
4098fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
4099fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
4100fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
4101fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
4102fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
4103fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
4104fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
4105fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
410671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  case AttributeList::AT_no_address_safety_analysis:
410771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    handleNoAddressSafetyAttr(S, D, Attr);
410871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    break;
4109fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
4110fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
4111fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
4112fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
4113fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
4114fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
4115db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
4116db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
4117db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4118db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
4119db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
4120db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4121db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
4122db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
4123db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4124db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
4125db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
4126db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4127db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
4128db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
4129db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4130db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
4131db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
4132db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4133db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
4134db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
4135db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4136db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
4137db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
4138db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4139db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
4140db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
4141db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4142db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
4143db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
4144db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4145db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
4146db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
4147db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4148db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
4149db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
4150db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4151db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
4152db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
4153db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
4154fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4155803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
415682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
415782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
415882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
41597d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
41607d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
4161803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
4162803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
4163803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
4164803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
416560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
416660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
416760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
416860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
41691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
41701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
417160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
417260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
417360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
417460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
417560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
417660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
417760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
417860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
417960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
41801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
418160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
418260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
41831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
418460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
418560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
4186803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
4187803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
4188f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
418960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
419060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
419111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
419298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
41939b79fc9c57dc9d541c2a5737c3e2c24cc68d485dRafael Espindola  }
419411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
419511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
419611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
419711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
419860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
419911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
4200dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
420111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
4202803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
4203803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
4204803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
42055f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access
42065f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier.
42075f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
42085f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          const AttributeList *AttrList) {
42095f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
42105f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    if (l->getKind() == AttributeList::AT_annotate) {
42115f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      handleAnnotateAttr(*this, ASDecl, *l);
42125f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    } else {
42135f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
42145f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      return true;
42155f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    }
42165f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  }
42175f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
42185f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  return false;
42195f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen}
42205f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
4221e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
4222e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
4223e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
4224e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
4225e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
4226e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
4227e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
4228e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4229e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
4230e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
4231e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
4232e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
4233e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
4234e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
4235e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
4236e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
4237e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
4238e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4239e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
4240e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
4241e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
4242e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
4243e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
4244e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
4245e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
4246e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
4247e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
4248e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
4249e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
42501dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// \#pragma weak needs a non-definition decl and source may not have one.
4251900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
4252900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
42537b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
4254e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
4255e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
4256900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
4257900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
4258900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
4259900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
4260900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
4261900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
4262900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
4263900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
4264900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
4265900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
4266900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
4267900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
4268900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
4269900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
4270900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
4271c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
4272900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
4273900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
4274900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
4275900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
4276900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
4277900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
4278900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
4279900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
4280900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
4281900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
4282900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
4283900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
42844278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
4285b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
4286e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
4287e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
4288ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
4289a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
429016573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
429116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
4292b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
4293b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
4294c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
4295b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
4296e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4297e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
4298e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
4299e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
43001dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
4301e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
43027b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
4303c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
4304c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
4305c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
4306c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
4307900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
4308cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
4309cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
4310cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
4311c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
4312c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
4313c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
4314c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
4315c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
4316c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
4317c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
4318c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
4319cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
4320e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4321e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
4322e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
43230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
43240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
43250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
432660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
432760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
4328d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
4329d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
433031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
433131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
433231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
433331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
433431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
433531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
433631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
433731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
433831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
433931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
434031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
434131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
4342d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
4343e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
4344e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
4345e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4346e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
43470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
43487f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
434960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
43510744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
43520744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
43530744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
43540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
43550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
43560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
435760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4358bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
43590744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
43600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
436160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
43620744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
436354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4364f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
4365f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
4366f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
4367f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
4368f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
4369a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
4370a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
4371a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
4372f85e193739c953358c865005855253af4f68a497John McCall    return false;
4373f85e193739c953358c865005855253af4f68a497John McCall
4374f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
4375f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
4376f85e193739c953358c865005855253af4f68a497John McCall}
4377f85e193739c953358c865005855253af4f68a497John McCall
4378f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
4379f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4380f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
4381f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
4382f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
4383f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
4384f85e193739c953358c865005855253af4f68a497John McCall    return;
4385f85e193739c953358c865005855253af4f68a497John McCall  }
43864e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (S.getLangOpts().ObjCAutoRefCount)
4387175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
438848d798ce32447607144db70a484cdb99c1180663Benjamin Kramer      // FIXME: we may want to suppress diagnostics for all
4389175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // kind of forbidden type messages on unavailable functions.
4390175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
4391175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag.getForbiddenTypeDiagnostic() ==
4392175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
4393175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
4394175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
4395175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
4396175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
4397f85e193739c953358c865005855253af4f68a497John McCall
4398f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4399f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4400f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
4401f85e193739c953358c865005855253af4f68a497John McCall}
4402f85e193739c953358c865005855253af4f68a497John McCall
44039257664568bf375b7790131a84d9a4fa30a5b7e3John McCallvoid Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
44049257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  assert(DelayedDiagnostics.getCurrentPool());
440513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
44069257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  DelayedDiagnostics.popWithoutEmitting(state);
44079257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
44089257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // When delaying diagnostics to run in the context of a parsed
44099257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // declaration, we only want to actually emit anything if parsing
44109257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // succeeds.
44119257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  if (!decl) return;
44129257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
44139257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // We emit all the active diagnostics in this pool or any of its
44149257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // parents.  In general, we'll get one pool for the decl spec
44159257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // and a child pool for each declarator; in a decl group like:
44169257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  //   deprecated_typedef foo, *bar, baz();
44179257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // only the declarator pops will be passed decls.  This is correct;
44189257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // we really do need to consider delayed diagnostics from the decl spec
44199257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  // for each of the different declarations.
442013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  const DelayedDiagnosticPool *pool = &poppedPool;
44219257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  do {
442213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    for (DelayedDiagnosticPool::pool_iterator
44239257664568bf375b7790131a84d9a4fa30a5b7e3John McCall           i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
44249257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      // This const_cast is a bit lame.  Really, Triggered should be mutable.
44259257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
4426eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
44272f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
44282f514480c448708ec382a684cf5e035d3a827ec8John McCall
4429eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
44302f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
4431e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        // Don't bother giving deprecation diagnostics if the decl is invalid.
4432e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        if (!decl->isInvalidDecl())
44339257664568bf375b7790131a84d9a4fa30a5b7e3John McCall          HandleDelayedDeprecationCheck(diag, decl);
44342f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
44352f514480c448708ec382a684cf5e035d3a827ec8John McCall
44362f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
44379257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        HandleDelayedAccessCheck(diag, decl);
44382f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
4439f85e193739c953358c865005855253af4f68a497John McCall
4440f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
44419257664568bf375b7790131a84d9a4fa30a5b7e3John McCall        handleDelayedForbiddenType(*this, diag, decl);
4442f85e193739c953358c865005855253af4f68a497John McCall        break;
444354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
444454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
44459257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  } while ((pool = pool->getParent()));
44462f514480c448708ec382a684cf5e035d3a827ec8John McCall}
44472f514480c448708ec382a684cf5e035d3a827ec8John McCall
444813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// Given a set of delayed diagnostics, re-emit them as if they had
444913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// been delayed in the current context instead of in the given pool.
445013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// Essentially, this just moves them to the current pool.
445113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCallvoid Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
445213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
445313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  assert(curPool && "re-emitting in undelayed context not supported");
445413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  curPool->steal(pool);
445513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall}
445613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
44572f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
44582f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
44590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
44602f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
4461c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    // A category implicitly has the availability of the interface.
4462c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4463c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis      return CatD->getClassInterface()->isDeprecated();
44642f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
44652f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
44662f514480c448708ec382a684cf5e035d3a827ec8John McCall}
44672f514480c448708ec382a684cf5e035d3a827ec8John McCall
44689c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
44692f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
44702f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
44712f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
44722f514480c448708ec382a684cf5e035d3a827ec8John McCall
44732f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4474ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
4475c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
4476ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
4477ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
4478b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  else if (DD.getUnknownObjCClass()) {
4479b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_fwdclass_message)
4480b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian      << DD.getDeprecationDecl()->getDeclName();
4481b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class);
4482b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  }
4483c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
4484c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
4485ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
448654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
448754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
44885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
44898e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
449089ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
449154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4492eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
4493b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
4494b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              UnknownObjCClass,
4495b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              Message));
449654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
449754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
449854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
449954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
45003a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
450154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4502d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian  if (!Message.empty()) {
4503c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
4504c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
4505d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian    Diag(D->getLocation(),
4506d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian         isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
4507d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian                                : diag::note_previous_decl) << D->getDeclName();
4508d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian  }
45098e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
4510350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian    if (!UnknownObjCClass) {
45118e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
4512350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian      Diag(D->getLocation(),
4513350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
4514350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian                                  : diag::note_previous_decl) << D->getDeclName();
4515350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian    }
451689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
45178e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
451889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
451989ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
45208e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
452154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4522