SemaDeclAttr.cpp revision aed9ea398a3fd8d488120728e2df4ac81c3b0c4b
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//                     The LLVM Compiler Infrastructure
46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source
66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details.
76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//  This file implements decl-related attribute processing.
116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h"
1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h"
166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h"
17384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
18b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski#include "clang/AST/DeclTemplate.h"
19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
20acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
21f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h"
22fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2319510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
25fe98da0fa352462c02db037360788748f95466f7John McCall#include "clang/Sema/Lookup.h"
26797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
289c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
30883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of
31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
32b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskienum AttributeDeclKind {
33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunction,
34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedUnion,
35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableOrFunction,
36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionOrMethod,
37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameter,
38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrBlock,
39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrParameter,
40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClass,
41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariable,
42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedMethod,
43db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  ExpectedVariableFunctionOrLabel,
44f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor  ExpectedFieldOrGlobalVar,
45f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor  ExpectedStruct
46883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall};
47883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall
48e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
49e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
5287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D,
53a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
5587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
63bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
656217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
66755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
68d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
69183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
723568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
75d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
76a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
7787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) {
7887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return getFunctionType(D, false) != NULL;
79a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
82d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
8487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) {
8587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isFunction(D)|| isa<ObjCMethodDecl>(D);
86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
88620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
9187c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
9287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isFunctionOrMethod(D))
93620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
9587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
9987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<BlockDecl>(D);
100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
101620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
102711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
10487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) {
105f85e193739c953358c865005855253af4f68a497John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
10687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
10787c44604325578b8de07d768391c1c9432404f5aChandler Carruth         isa<ObjCPropertyDecl>(D);
108711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
110d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
111d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
112620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
11387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) {
11487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
11572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
116620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
11787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
118d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
119d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
1203568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1213568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
122d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
123d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
12587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) {
12687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
12772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
12887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
129d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
13087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_size();
1313568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
13487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
13572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
13687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
137d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
1403568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1413568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
14287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) {
14387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
1445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
14587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->getResultType();
1465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
14887c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) {
14987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D)) {
15072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
15287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
153db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
154d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
15587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    return cast<ObjCMethodDecl>(D)->isVariadic();
1563568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
15987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) {
16087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
16107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
16207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
166183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
167b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
169bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
170506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
171506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
174506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
175bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
181085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1826217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
183085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
184085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1866217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
187085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
189bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
191465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
192085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
197b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May
198b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
1991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
2001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth                                  unsigned int Num) {
2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (Attr.getNumArgs() != Num) {
2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    return false;
2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  }
2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  return true;
2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth}
2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
209db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
210b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May
211b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error.
212b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                  unsigned int Num) {
214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (Attr.getNumArgs() < Num) {
215db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
216db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return false;
217db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  return true;
220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski///
223fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var
224fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable
225fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
22639997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) {
227fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (isa<FieldDecl>(D))
228fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return true;
22939997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const VarDecl *vd = dyn_cast<VarDecl>(D))
230fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
231fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
232fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
235b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool.
236b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) {
237b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = Exp->getType();
238b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  return QT->isBooleanType() || QT->isIntegerType();
239b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
240b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
241aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
242aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// Check to see if the type is a smart pointer of some kind.  We assume
243aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// it's a smart pointer if it defines both operator-> and operator*.
244aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchinsstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const QualType QT) {
245aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins  if (const RecordType *RT = QT->getAs<RecordType>()) {
246aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins    DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
247aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins      S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
248aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins    if (Res1.first == Res1.second)
249aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins      return false;
250aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
251aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins    DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
252aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins      S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
253aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins    if (Res2.first != Res2.second)
254aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins      return true;
255aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins  }
256aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins  return false;
257aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins}
258aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type.
261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message.
262fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise
263fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
264ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
265ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                       const AttributeList &Attr) {
26639997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
267fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
26839997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer    if (QT->isAnyPointerType())
269fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
270aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
271aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins    if (threadSafetyCheckIsSmartPointer(S, QT))
272aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins      return true;
273aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins
274ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
275fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
276fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
277fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
278fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
279fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
280fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
281fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
282fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
283b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points
284b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit.
2857d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) {
2867d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const RecordType *RT = QT->getAs<RecordType>())
287b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return RT;
2887d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2897d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  // Now check if we point to record type.
2907d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  if (const PointerType *PT = QT->getAs<PointerType>())
2917d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer    return PT->getPointeeType()->getAs<RecordType>();
2927d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer
2937d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer  return 0;
294b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
295b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
2963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType
297ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// resolves to a lockable object.
29883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchinsstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
29983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins                                   QualType Ty) {
30083cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  const RecordType *RT = getRecordType(Ty);
30183cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins
30283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  // Warn if could not get record type for this argument.
303d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT) {
304ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
30583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      << Attr.getName() << Ty.getAsString();
30683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
3073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
308634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  // Don't check for lockable if the class hasn't been defined yet.
309634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins  if (RT->isIncompleteType())
31083cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
31183cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  // Warn if the type is not lockable.
312d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer  if (!RT->getDecl()->getAttr<LockableAttr>()) {
313ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
31483cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins      << Attr.getName() << Ty.getAsString();
31583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    return;
3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
319b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
320ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// from Sidx, resolve to a lockable object.
3213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with.
3223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function
3233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list.
324ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
3253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         const AttributeList &Attr,
3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                         SmallVectorImpl<Expr*> &Args,
327b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         int Sidx = 0,
328b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                         bool ParamIdxOk = false) {
3293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
330b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    Expr *ArgExp = Attr.getArg(Idx);
3313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
332ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    if (ArgExp->isTypeDependent()) {
333ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // FIXME -- need to check this again on template instantiation
334ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      Args.push_back(ArgExp);
335ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski      continue;
336ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski    }
337b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
33879747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
33979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      // Ignore empty strings without warnings
34079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (StrLit->getLength() == 0)
34179747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        continue;
34279747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
343ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // We allow constant strings to be used as a placeholder for expressions
344ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      // that are not valid C++ syntax, but warn that they are ignored.
345ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
346ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins        Attr.getName();
347ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      continue;
348ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    }
349ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins
3503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    QualType ArgTy = ArgExp->getType();
351b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
35279747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // A pointer to member expression of the form  &MyClass::mu is treated
35379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    // specially -- we need to look at the type of the member.
35479747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins    if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
35579747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins      if (UOp->getOpcode() == UO_AddrOf)
35679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
35779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins          if (DRE->getDecl()->isCXXInstanceMember())
35879747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins            ArgTy = DRE->getDecl()->getType();
35979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins
3603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // First see if we can just cast to record type, or point to record type.
3613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    const RecordType *RT = getRecordType(ArgTy);
362b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    // Now check if we index into a record type function param.
3643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if(!RT && ParamIdxOk) {
3653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
366b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
367b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      if(FD && IL) {
368b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        unsigned int NumParams = FD->getNumParams();
369b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        llvm::APInt ArgValue = IL->getValue();
3703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
3713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
3723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
373b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
374b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski            << Attr.getName() << Idx + 1 << NumParams;
375ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins          continue;
376b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        }
3773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
378b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      }
379b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
380b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
38183cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins    checkForLockableRecord(S, D, Attr, ArgTy);
382b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
3833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    Args.push_back(ArgExp);
384b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
385b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski}
386b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
387e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
388e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
389e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
390e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
3913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
3923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
3933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
3943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
395fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
396fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
397fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
398fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
399fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
400fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
401fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
402fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
403fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
404fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
405b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
406fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
407fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
408fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
409ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
410fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
411fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
412fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
413768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
414fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
415768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
416fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
418db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,
419b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                bool pointer = false) {
420db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
421db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
422b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
423db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
424db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
425db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
426db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
427db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
428b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
429db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
430db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
431db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
432ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
433db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
434db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
435ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  SmallVector<Expr*, 1> Args;
436ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // check that all arguments are lockable objects
437ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
438ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  unsigned Size = Args.size();
439ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size != 1)
440ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
441ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr *Arg = Args[0];
442b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
443db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (pointer)
444768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
4453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 S.Context, Arg));
446db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
447768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
448db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
449db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
450db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
451fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
452fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
453fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
454fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
455fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
456fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
457fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
4581748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski  // FIXME: Lockable structs for C code.
459fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
460fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
461fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
462fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
463fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
464fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
465fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
466768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
467fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
468768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
469fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
470fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
471fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
472fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
473fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
474fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
475fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
476fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
477fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
478b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
479fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
480fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
481fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
482fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
483fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
484768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
485fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
486fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
487fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
48871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D,
489ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins                                      const AttributeList &Attr) {
49071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  assert(!Attr.isInvalid());
49171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
49271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!checkAttributeNumArgs(S, Attr, 0))
49371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
49471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
49571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
49671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
49771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany      << Attr.getName() << ExpectedFunctionOrMethod;
49871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    return;
49971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  }
50071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
50171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
50271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany                                                          S.Context));
50371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany}
50471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany
505db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,
506db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski                                   bool before) {
507db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
508db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
509b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
510db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
511db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
512db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
513b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  ValueDecl *VD = dyn_cast<ValueDecl>(D);
514b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!VD || !mayBeSharedVariable(D)) {
515db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
516b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      << Attr.getName() << ExpectedFieldOrGlobalVar;
517db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
518db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
519db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
520ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that this attribute only applies to lockable types.
521b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  QualType QT = VD->getType();
522b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!QT->isDependentType()) {
523b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    const RecordType *RT = getRecordType(QT);
524b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
525ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
526b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski              << Attr.getName();
527b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski      return;
528b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    }
529b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
530b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
532ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  // Check that all arguments are lockable objects.
533ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
5343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
535ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
536ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
537ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
5383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
539db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (before)
540768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
5413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                    StartArg, Size));
542db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
543768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
5443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                   StartArg, Size));
545db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
546db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
547db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
548b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                              bool exclusive = false) {
549db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
550db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
551db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
553b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that the attribute is applied to a function
554b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
555db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
556db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
558db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
559db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
560b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
5613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
562ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
5633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
5653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
566db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
567768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
5683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           S.Context, StartArg,
5693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                           Size));
570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
571768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
5723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        S.Context, StartArg,
5733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                        Size));
574db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
575db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr,
577b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                 bool exclusive = false) {
578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
579db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
580b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
583b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
586db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
587db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
589b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isIntOrBool(Attr.getArg(0))) {
590b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
591b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski        << Attr.getName();
592b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
593b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  }
594b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
5953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 2> Args;
596b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
597ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
5983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
5993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
601db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
602768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
6033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              S.Context,
60469f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                              Attr.getArg(0),
6053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                              StartArg, Size));
606db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
607768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
60869f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           S.Context,
60969f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           Attr.getArg(0),
61069f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski                                                           StartArg, Size));
611db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
612db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
613db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr,
614b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    bool exclusive = false) {
615db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
616db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
617b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
620b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
621db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
622db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
623db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
624db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
625db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
626b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
628ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
6293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
630ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
631ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
632ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
6333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
634db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  if (exclusive)
635768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
6363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            S.Context, StartArg,
6373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                            Size));
638db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  else
639768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
6403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         S.Context, StartArg,
6413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                         Size));
642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D,
645b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                const AttributeList &Attr) {
646db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
647db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
648db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  // zero or more arguments ok
649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
650b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
651db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
652db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
656b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
6573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
658ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
6593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
6603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr **StartArg = Size == 0 ? 0 : &Args[0];
6613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
662768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
6633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                  StartArg, Size));
664db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
666db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D,
667b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                   const AttributeList &Attr) {
668db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
670b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 1))
671db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
6723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  Expr *Arg = Attr.getArg(0);
673db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
674b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
675db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
676db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
677db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
678db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
679db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
6803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (Arg->isTypeDependent())
681b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski    return;
682b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski
6833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  // check that the argument is lockable object
68483cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins  checkForLockableRecord(S, D, Attr, Arg->getType());
6853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
686768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg));
687db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
688db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
689db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D,
690b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski                                    const AttributeList &Attr) {
691db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  assert(!Attr.isInvalid());
692db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
693b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
694db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
695db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
696b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
697db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
698db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
699db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    return;
700db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  }
701db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
702b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski  // check that all arguments are lockable objects
7033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  SmallVector<Expr*, 1> Args;
704ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
7053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  unsigned Size = Args.size();
706ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  if (Size == 0)
707ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins    return;
708ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins  Expr **StartArg = &Args[0];
7093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
710768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
7113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski                                                 StartArg, Size));
712db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski}
713db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
714db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski
7151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
7161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
71787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
718545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
719803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
720545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
7216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
722bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
7249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7259cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
7269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7279cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
7289cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
729f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
730e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    SourceLocation TemplateKWLoc;
731f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
732f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
7334ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
734e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id,
735e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                          false, false);
7364ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
7374ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
7384ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
7394ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
7409cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
7419cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
7421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
7439cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
7441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
7457a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
7466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7479cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
7489cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
7499cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
7509ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
7519cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
752ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
753a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
754bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7559cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
7569cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
7576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
7621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
7636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
764bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
76587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
766768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
76787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
7686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
7696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
7706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
771803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
772fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
77308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
7746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
775768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
7766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
7773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
7786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
78187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
782768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
783c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
784c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
785c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
786c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
7871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
78896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
7891731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
79096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
791bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
79263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
79387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
79463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
795768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
79663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
79763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
79863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
7994ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
80063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
80163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8022f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
8032f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // The IBOutlet/IBOutletCollection attributes only apply to instance
8042f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // variables or properties of Objective-C classes.  The outlet must also
8052f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  // have an object reference type.
8062f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
8072f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
8080bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
8092f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << VD->getType() << 0;
8102f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
8112f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
8122f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
8132f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
8142f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
815f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
8162f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek        << Attr.getName() << PD->getType() << 1;
8172f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek      return false;
8182f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    }
8192f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
8202f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  else {
8212f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
8222f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek    return false;
8232f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  }
824f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
8252f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  return true;
8262f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek}
8272f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
82963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
8301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
83163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
8322f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
8332f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
83463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
83563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
8362f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
83796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
83896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
8391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
8401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
841857e918a8a40deb128840308a318bf623d68295fTed Kremenek
842857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
843a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
844857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
845857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
846857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
847857e918a8a40deb128840308a318bf623d68295fTed Kremenek
8482f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek  if (!checkIBOutletCommon(S, D, Attr))
849857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
8502f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek
851a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
852a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
853f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian    II = &S.Context.Idents.get("NSObject");
8543a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
855b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
85687c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
857a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
858a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
859a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
860a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
861b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
862a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
863a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
864a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
865a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
866f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
867a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
868a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
869a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
870f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
871f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis                                                   QT, Attr.getParameterLoc()));
872857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
873857e918a8a40deb128840308a318bf623d68295fTed Kremenek
874d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
87568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
87668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
87768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
87868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
87968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
88068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
88168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
88268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
88368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
88468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
88568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
88668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
88768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
88868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
8891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
890bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
891bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
89287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
893fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
894883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
895eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
896eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
897bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
89807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
89907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
90087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
90187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
902eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
903eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
9045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
905bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
906eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
907eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
908bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
909bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
910eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
9117a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
912eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
913ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
914ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
915fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
916fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
917eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
918eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
919bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
920eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
921bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
922eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
923fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
92430bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
925eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
926eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
928465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
92907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
93007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
93107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
93207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
93307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
93407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
93507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
93607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
93707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
938eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
939eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
94087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
941d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
94268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
943dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
944eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
945c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
946fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
9477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
948eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
949bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
950eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
951eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
952bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
953bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
954bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
9557fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
95687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
95787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
958d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
959dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
960d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
96146bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
962bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
963ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
96460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
96560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
96660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
96760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
96860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
9697fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
97060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
971eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
9727fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
9737fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
9747fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
975dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
976768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
977cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
978eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
979eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
9801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
981dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
982dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
983dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
986dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
9872a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
9882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
989dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
990dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
991dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
992dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
993dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
994dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
995dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
996cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
9972a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
9982a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
999cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
1000dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1002dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
10042a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
10052a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
1006cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
1008dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1009dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1010dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
10112a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
10122a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
1013cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
1014dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
1015dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
1016dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
10192a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
10202a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
10212a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
10222a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
1023dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1024dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
102587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
1026883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1027883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1030dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
103107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
103207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
103387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
103487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1035dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
1037dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
1040dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
1041dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
1043dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10442a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
10452a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
1046dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
10477a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
1048dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
1049dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1052dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
1053dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1055dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1056dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
1057dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1058dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
1059dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1060dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1061dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
1062dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1063dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
106407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
106507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
106607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
106707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
106807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
106907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
107007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
107107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
107207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1073dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
1074cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
1075cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
1076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
107787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
1078dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1079dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
1080dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
1081cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
1082dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
1083dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
1084dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
1085dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1086dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1087dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
1089dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
1090dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
10917a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
1092dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
1093dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1094dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1095dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
1096dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
1097dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
1098dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
1099dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1100dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1101dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
1102dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1103dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
1104dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1105dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
1106cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
110787c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
110887c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
1109cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
1110cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
1111cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1112cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
1113cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
1114cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1115cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
1116dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
1117dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
1118dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
1119dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
1120dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
1121dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1122dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1123dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
1124dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
1125dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
1126cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1127cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1128cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1129cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
1130dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
1131cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
113287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
1133cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
1134dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
1135dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
1136332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
1137332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
1138332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
1139332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
1140332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
1141332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
1142332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1143332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1144332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
1145332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
1146332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
1147332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
1148332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1149332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
1150332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
1151332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1152332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
11551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
115711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
115811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
115911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
116011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
116111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
116287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1163332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1164883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1165332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
1166332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
1167332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
116887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1169332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
117111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
117311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
117411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
117711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
117811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
118087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
11817a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
11827a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1183332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
11847a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
118511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
118611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
118711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
118811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
118911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
119011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
119111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
119211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
119311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
119411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
119511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
119611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
119711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
119811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
119911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
120011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
120111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
120211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
120311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
120411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1205332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
1206332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
120711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
120811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
120911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
121011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
121111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
121211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
121311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
121411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
12157a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
121611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
121711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
121811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
12195cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
122011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
122111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
122211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
122311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
122411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
122511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
1226768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1227f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
122811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
122911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
1230768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
123111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
123211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
12331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
12346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1235545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
12363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1239bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12407a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
12416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
12426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1243bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12445cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1245fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
12476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1249bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1250bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1251f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1252f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
1253f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
1254f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
12556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
1256bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1257768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
1258f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
12596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1262dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
12631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1264dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1265dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
126687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1267dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1268883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
1269dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
1270dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
1271dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
1272768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
1273dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
1274dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
12751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
12761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1277dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1278831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
12793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1280af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
1281af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
12825bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
128387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
12845bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1285883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
12865bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
12875bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1288bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1289768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
1290af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
1291af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
12921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1293dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
1294831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
129576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
129676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
129776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
12981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
129987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
13001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
13012cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1302768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
13032cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
13042cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
1305fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
1306fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
13072cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
130876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
130976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
13101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
131134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
13121731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
131334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
131434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
1315768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
131634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
131734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
13181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
131956aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
132087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1321768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
1322722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1323722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1324883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1325a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1326a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
13271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
132856aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
132987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
1330768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
1331722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
1332722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1333883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
1334a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
1335a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
13361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
133787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
1338711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1339711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
1340711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
134187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
1342711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1343883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
1344711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
1345711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1346711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1347768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
1348711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
1349711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1350711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1351831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1352711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1353711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
1354711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
1355711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
1356711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
1357711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
1358b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
1359b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
13611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1362b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1363b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1364b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
1365b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
13661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
13671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
1368b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
136987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
137087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
13713ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
13723ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
1373e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
1374e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
1375b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
1376883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1377b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
137819c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
13796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1380b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
1381768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
13826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
138435cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
13851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
138635cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
138735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
138835cc9627340b15232139b3c43fcde5973e7fad30John Thompson
1389f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
1390f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
1391f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
1392f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
1393f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
139435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
139535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
139635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
139735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
139835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
139935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
140035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
140135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
140235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
140335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
140435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
140535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
140635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
140735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
140835cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
140987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
141035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1411883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
141235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
141335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
141435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
141587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
141635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
141735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
141835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
141935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
142087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
142101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
142201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
142301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
142401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
142501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
142601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
142701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
142801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
142901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
143001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
143101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
143201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1433f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1434f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
143501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
143601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
143701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
143801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
143901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
144001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
144101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1442768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
144335cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
144435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
14451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
144687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1447bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1448883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1449bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1450bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1451bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1452bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1453bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
14541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
145573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1456831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
14573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
145873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
145973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1460bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
146187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
146287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1463fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1464883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
146573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
146673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1467bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1468768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
146973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
147073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
1471f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
1472f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola                                   const AttributeList &Attr) {
1473f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  // check the attribute arguments.
1474f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (Attr.hasParameterOrArguments()) {
1475f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1476f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1477f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1478f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1479f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  if (!isa<FunctionDecl>(D)) {
1480f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1481f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola      << Attr.getName() << ExpectedFunction;
1482f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    return;
1483f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  }
1484f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
1485f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
1486f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola}
1487f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola
14881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1489b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1490831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1491b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1492b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1493b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1494bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
149587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1496186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1497b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1498b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1499b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
150087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1501b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1502883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1503b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1504b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1505bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1506768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
1507b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1508b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
15091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1511bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1512bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
15133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1514bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
15173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
15187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
15193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1520ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1521ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1522fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
15243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1528bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
152987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1530fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1531883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1535768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
1536f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
15373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1541bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1542bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
15433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1544bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
15473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
15487a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
15493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1550ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1551ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1552fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
15543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
15553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
15563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
15573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1558bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
155987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1560fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1561883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
15623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
15633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
15643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1565768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
1566f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
15673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
15683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
15691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1570951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1571951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1572bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1573c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1574c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1575951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1576c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
15775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1578951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1579951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1580c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1581951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1582951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1583c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1584c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1585951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
15866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1587bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1588768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str));
15896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1592951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1593951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1594bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1595bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1596bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1597951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1598c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
15995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1600951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1601951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1602c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1603951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1604c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1605c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1606c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1607951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1608c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1609768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str));
1610bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1611bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1612742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1613742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1614742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1615742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1616742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1617742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1618742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1619742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1620742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1621768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                                          Attr.getRange(), S.Context));
1622742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1623742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1624b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beardstatic void handleObjCRootClassAttr(Sema &S, Decl *D,
1625b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard                                    const AttributeList &Attr) {
1626b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (!isa<ObjCInterfaceDecl>(D)) {
1627b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1628b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1629b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1630b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1631b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  unsigned NumArgs = Attr.getNumArgs();
1632b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  if (NumArgs > 0) {
1633b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1634b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    return;
1635b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  }
1636b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
1637b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
1638b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard}
1639b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
164071207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
1641e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                            const AttributeList &Attr) {
1642341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  if (!isa<ObjCInterfaceDecl>(D)) {
1643341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
1644341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian    return;
1645341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian  }
1646341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian
1647e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1648e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  if (NumArgs > 0) {
1649e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1650e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    return;
1651e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian  }
1652e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
165371207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
1654e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian                                 Attr.getRange(), S.Context));
1655e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian}
1656e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
16571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
16581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
16590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
16600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
16610a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
16630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
16640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
16650a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
16660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
16670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16680a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
16690a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16700a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16710a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
16720a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
16730a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1674b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
16750a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1676c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
16770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
16780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
16793b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Deprecated.Version)) {
16800a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16810a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
16820a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16830a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16840a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16850a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16860a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
16873b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Introduced.Version <= Obsoleted.Version)) {
16880a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
16890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
16910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
16920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
16930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
16940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
16953b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor      !(Deprecated.Version <= Obsoleted.Version)) {
16960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
16970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
16980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
16990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
17000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
17010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1702006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  StringRef Str;
1703006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  const StringLiteral *SE =
1704006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
1705006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian  if (SE)
1706006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian    Str = SE->getString();
1707006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian
1708768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context,
17090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
17100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
17110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1712b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1713006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                IsUnavailable,
1714006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian                                                Str));
17150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
17160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
17171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
17186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
17191731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
17206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1721bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17227a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
17236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
17246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1725bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17265cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1727fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
17283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
17296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1731bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1733cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1734bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1735c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1736cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1737c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1738cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1739c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1740cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
17414188760f6bb20f91c6883dffd89204419f852deeJohn McCall  else if (TypeStr == "protected") {
17424188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // Complain about attempts to use protected visibility on targets
17434188760f6bb20f91c6883dffd89204419f852deeJohn McCall    // (like Darwin) that don't support it.
17444188760f6bb20f91c6883dffd89204419f852deeJohn McCall    if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
17454188760f6bb20f91c6883dffd89204419f852deeJohn McCall      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
17464188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Default;
17474188760f6bb20f91c6883dffd89204419f852deeJohn McCall    } else {
17484188760f6bb20f91c6883dffd89204419f852deeJohn McCall      type = VisibilityAttr::Protected;
17494188760f6bb20f91c6883dffd89204419f852deeJohn McCall    }
17504188760f6bb20f91c6883dffd89204419f852deeJohn McCall  } else {
175108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
17526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1754bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1755768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type));
17566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
17576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
17591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1760d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1761d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
176287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1763883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1764d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1765d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1766d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
176787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
176887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
176987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1770d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1771d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
177287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1773d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
177487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1775d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1776d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1777d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
17785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1779d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1780d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1781d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1782d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1783d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1784d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1785d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1786d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1787d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1788d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1789d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1790d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1791d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1792d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1793d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1794d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
179587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1796d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1797d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1798d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1799f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1800f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1801f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1802f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1803f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1804f85e193739c953358c865005855253af4f68a497John McCall    return;
1805f85e193739c953358c865005855253af4f68a497John McCall  }
1806f85e193739c953358c865005855253af4f68a497John McCall
1807768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
1808f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1809d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1810d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
18111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
18121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
18131731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
18140db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1815bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18160db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
18170db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
18180db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
18190db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
18200db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1821bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1822768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
18230db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
18240db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
18251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1826fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
18272b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1828fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1829fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1830162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1831fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1832fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
18336217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1834fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1835fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1836fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1837fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1838f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  else if (!isa<ObjCPropertyDecl>(D)) {
1839f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // It is okay to include this attribute on properties, e.g.:
1840f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1841f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
1842f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    //
1843f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // In this case it follows tradition and suppresses an error in the above
1844f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek    // case.
18459b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
1846f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek  }
1847768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
1848fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1849fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1850bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
18511b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1852f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
18532b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1854f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1855f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1856f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1857f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1858f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1859f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1860f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1861f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1862768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
1863f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1864f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
18651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1866bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1867fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
18683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
18699eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18709eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1871bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
18733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
18749eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1876bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1877cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
187892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
18799eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
18809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1881fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
18823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
18839eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
18849eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1885bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1886768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
18879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
18889eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
18891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1890770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1891770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1892bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1893770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1894bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1895bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18963323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned sentinel = 0;
1897770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
18987a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1899770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1900ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1901ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1902fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
19033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1904770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1905770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1906bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19073323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if (Idx.isSigned() && Idx.isNegative()) {
1908fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1909fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1910770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1911770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
19123323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall
19133323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    sentinel = Idx.getZExtValue();
1914770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1915770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
19163323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall  unsigned nullPos = 0;
1917770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
19187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1919770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1920ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1921ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1922fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
19233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1924770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1925770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1926770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19283323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
1929770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1930770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1931fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1932fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1933770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1934770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1935770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1936770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
193787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
19383323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
1939897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1940897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1941897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1942897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1943bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1944897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
19453bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1946770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1947bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
194887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1949770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
19503bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1951770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
19522f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1953a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
1954a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    if (!BD->isVariadic()) {
1955a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
1956a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman      return;
1957a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman    }
195887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
19592f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1960daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
196187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1962f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
19632f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
19643bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
19653bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
19662f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
19672f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1968ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
19692f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1970883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
19712f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
19722f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1973770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1974fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1975883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1976770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1977770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1978768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
1979f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1980770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1981770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
19821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1983026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
19841731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1985026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1986026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1987f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1988026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1989883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1990026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1991026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1992bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1993f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1994f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1995f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1996f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1997f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1998f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1999f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
2000f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2001f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
2002f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
2003f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
2004f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
2005768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
2006026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
2007026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
20081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
201087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
201187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
20126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
20146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
201587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
201613c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    if (isa<CXXRecordDecl>(D)) {
201713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
201813c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian      return;
201913c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian    }
202087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
202187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
2022f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
2023f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
2024f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
202587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
2026332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
2027332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
2028332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
202987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
20306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
2032bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2033768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
20346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
20381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
20396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
20416e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20426e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
20436e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
20440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
20450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
20460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
20470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
20480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
2049def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2050bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
205190eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2052def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
2053def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
2054c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2055883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
20566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20576e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
20586e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
20596e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
2060768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
20616e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
20626e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
20631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
20641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
20656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
20661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
20676f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
20686f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20696f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
20706f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
20717a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
20726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
2073ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
2074ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
20756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
20766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
20776f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
20786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
20796f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
20806f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
2081768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
2082cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
20836f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
20846f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
20856f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
20861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
208717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
20881731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
208917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
209017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
209117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
209217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
20937a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2094797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
209517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
2096797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
209717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
209817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
20991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2100797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
2101bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
2102a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
2103a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2104a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
2105797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
2106797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
21071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2108a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
2109a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2110a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2111a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
2112a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
2113a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
2114768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context,
2115f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
211617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
211717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
21186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2121831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
21223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
21236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2125b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
212687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2127b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
2128ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis      Existing->setRange(Attr.getRange());
2129b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2130768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
2131b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
21326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
21336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2135232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
2136831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
21373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2138232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2139232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
2140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
214187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2142b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
2143ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis     Existing->setRange(Attr.getRange());
2144b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
2145768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
2146b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2147232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2148232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
21491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2150232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
21511731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2152232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
2153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2154768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
2155232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
2156232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
21571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2158bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
2159f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2160f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2161f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2162bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2163f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
2164f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2165f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2166f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
216887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
2169bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2170f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
2171f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2172f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2173f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2175f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
2176c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
2177f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
2178f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2179f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
2180f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
2181f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
2182f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
2183f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2184f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2185bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2186f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2187f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
2188f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2189f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
2190f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2191f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2192f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2193f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2194f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
2195f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
2196f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
2197f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
2198f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
2199f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
2200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
220189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
220289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
220389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
220489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
2205b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2206b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
2207f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
220889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
220989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
221089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
221189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
2212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2213768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
22145f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
2215f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
2216f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
2217bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
2218bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
22191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
22201731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
22215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22221731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
222387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
22245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2225883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
222807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
222907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
223007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
223187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
223287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
22335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
223407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
22355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
22367a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
22375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
2238ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2239ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
22405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
22415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
22425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2244bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
22465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
22475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
22485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
22495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
2250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
2252bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
225307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
225407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
225507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
225607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
225707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
225807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
225907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
226007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
226107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
22625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
226387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2264bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
22665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
22675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22696217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2272bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
22735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2275bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
227687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
22775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
22785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
22795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
22806217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
22815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
22825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2283bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
22845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
22855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
2286bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
2287bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2288768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
228907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
22905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
22915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
22922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
22932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
22942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
22952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
22962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
22973c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
22982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
22992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
23002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
23012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
23022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
23035f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
23042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
23052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
23062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
23072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
23082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
23092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
23102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
23112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
23122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
23132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
231469d53845c68a4f01920b58ba6ce507d78220689cJean-Daniel Dupas      Format == "strfmon" || Format == "cmn_err" || Format == "vcmn_err" ||
2315cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
2316cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
23172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
23182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2319bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
2320bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
23213c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
23223c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
23232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
23242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
23252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
2326521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
2327521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
23281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
23291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
23304e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!S.getLangOpts().CPlusPlus) {
2331521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2332521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2333521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2334521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
233587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
2336b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2337b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2338b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2339b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
234087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
2341b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
2342b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
2343b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
2344b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2345b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
2346b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
2347b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
2348b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2349521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
2350521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2351521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2352521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2353521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
23547a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
2355b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
2356521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
2357521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2358521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2359521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2360521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
2361521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2362521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2363521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
23649f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
2365521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
2366521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2367521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
2368521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
2369521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
2370521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
2371768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
2372f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
2373521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
2374521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
2375bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2376bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
23771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
23786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2379545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
2380fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
23813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
23826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2385545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
23863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
23876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
239087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
2391fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2392883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
23946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
23956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
239607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
239707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
239887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
239987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
24006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
24016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24025f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
24036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
24052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
24062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
24072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
24082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
24092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
24103c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
24113c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
24123c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
24133c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
24142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
2415fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
241601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
24176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
24217a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
2422803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
2423ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2424ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
2425fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
24263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
24276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2431fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
24323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
24336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
24376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
2438bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24394a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
24404a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
244107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
244207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
244307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
24444a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
24454a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
24464a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
24474a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
24481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
245087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
24516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
2453085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
2454fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2455fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
2456085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
2457085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
24582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
2459390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
2460390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
2461803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
2462390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
2463fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2464fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
24656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
2466bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
24676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
24686217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2469390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
2470fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2471fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
24726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
24767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
2477803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
2478ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
2479ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
2480fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
24813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
24826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
24836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
24866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
248787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
24886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
24896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
249087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
24916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
24926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
24936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
24963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
24972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
24986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2499fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2500fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
25016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
25026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
25036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
25046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2505fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
25063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
25076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2510b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2511b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
251287c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
251387c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2514b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2515b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2516b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2517b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2518b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2519b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2520b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2521b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2522ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis        f->setRange(Attr.getRange());
2523b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2524b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2525b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2526b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
2527768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format,
2528cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
25292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
25306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
25331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
25346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
25351731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
25366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25371731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
25386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
25400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
254187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
25420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
25430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
25440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
254587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
25460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
25470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2548fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2549883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
25506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
25516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25535e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall  if (!RD->isCompleteDefinition()) {
2554bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
25550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
25560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
25580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
255917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
256017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
25610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
25620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
25630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2565bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
25670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
256890cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2569bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
257090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
257190cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
25720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
25730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2574bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
25750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
25760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
25770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
25780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
25790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
25800c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
25810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
25820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2583bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
25840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2585bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
25860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
25870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
25880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2589bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
25900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
25910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2592bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2593bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2594bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
25956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2596768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
25976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
25986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
25991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
26006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
26011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
26026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
26047a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2605797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2606bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
26076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
26086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
26096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2610797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
26116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
261377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge
261477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  // Don't duplicate annotations that are already set.
261577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  for (specific_attr_iterator<AnnotateAttr>
261677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       i = D->specific_attr_begin<AnnotateAttr>(),
261777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
261877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge      if ((*i)->getAnnotation() == SE->getString())
261977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge          return;
262077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge  }
2621768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
2622f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
26236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
26246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
26266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2627545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
26283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
26296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2631bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2632bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2633bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2634bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
26356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2636545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2637768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0));
26384ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
26394ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
26404ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2641768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0));
26424ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
26434ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
2644768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
26450b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  // FIXME: Handle pack-expansions here.
26460b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne  if (DiagnoseUnexpandedParameterPack(E))
26470b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne    return;
26480b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne
26494ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
26504ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2651768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
26526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
26536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2654bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2655768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  SourceLocation AttrLoc = AttrRange.getBegin();
2656cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
265749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
2658282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  ExprResult ICE =
2659282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith    VerifyIntegerConstantExpression(E, &Alignment,
2660282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith      PDiag(diag::err_attribute_argument_not_int) << "aligned",
2661282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith      /*AllowFold*/ false);
2662282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  if (ICE.isInvalid())
266349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
2664396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
26654ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
26664ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2667396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2668396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2669396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2670282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take()));
2671cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2672cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2673768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
2674cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2675cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2676768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS));
2677cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
26786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2679fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2680d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2681bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2682fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2683bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2684bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2685bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
26861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2687fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2688fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2689fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2690fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
26911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2692fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
26931731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2694fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2695fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2696fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
26970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2700210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
27015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2704210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2705210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2708fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
270973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2710210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
271273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
271373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
271473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
271573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
271673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
271773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
271873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
271973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
272073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
272173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
272273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
272373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
272473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
272573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
272673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
272773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2728fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2729fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2730fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2731fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2732210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
2733bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2734210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
2735bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getCharWidth();
2736fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2737fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2738210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
2739bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
2740fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2741fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2743fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2744162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2745fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2747fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2748fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2749fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2750768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << "mode" << Attr.getRange();
2751fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
275373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2754183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
275573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
275673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
27572ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
275873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
275973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
276073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
276173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
276273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
276373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
276473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
276573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
276673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2767390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2768390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2769390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2770390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2771f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2772f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2773fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2775fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
27763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2777fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
27793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2780fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2781fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
278273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
278373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
278473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
278573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2786fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2788fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2790fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2791fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
279273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
279373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
279473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
279573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2796fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
27970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2798fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
27990b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2800fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2801fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2802fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
28030b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2804fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
28050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2806fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
28070b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2808fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2809fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2810fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
28110b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2812fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2813bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2814aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2815aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2816aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2817fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2818bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (S.Context.getTargetInfo().getLongWidth() == 64)
2819aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2820aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2821aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2822fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
282373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
282473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
282573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2826f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2827f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2828f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2829f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2830f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2831f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2832f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2833f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2834f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
283573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2836fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2837fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
283873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
283973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2840fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2841fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2842fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2843162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2844ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2845a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2846ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2847fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2848fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
28490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
28501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2851d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
28521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2853d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2854e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
285587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2856d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2857883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2858d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2859d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2860bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2861768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
2862d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2863d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
28641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
28655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
28661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28675bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
28681731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2869bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
287087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28715bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2872883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28735bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
28745bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2875bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2876768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
28775bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
28785bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
28791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
28801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
28817255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
28821731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28837255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28841731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
28857255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
288687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
28877255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2888883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
28897255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
28907255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
28917255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2892768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
2893f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
28947255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
28957255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
28961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2897ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2898ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2899831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2900ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2901ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2902ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2903ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
290487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2905ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2906883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2907ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2908ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2909ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2910768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
2911ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2912ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2913ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2914ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2915ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2917ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2918ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2919ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2920ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2921ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2922ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2923ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
292487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2925ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2926883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2927ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2928ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2929ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2930768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
2931ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2932ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2933ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2934ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2935ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2937ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2938ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29391731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2940ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2941ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
294287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2943ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2944883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2945ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2946ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2947ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
294887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
29492c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2950723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
29512c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
29522c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
29532c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
29542c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
29552c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
29562c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
29572c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
29582c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
29592c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
29602c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
29612c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
29622c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2963768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
2964ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2965ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2966ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2967ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2968ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2970ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2971ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29721731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2973ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29741731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2975ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
297687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2977ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2978883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2979ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2980ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2981ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2982768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
2983ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2984ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2985ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2986ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2987ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
29881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2989ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2990ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
29911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2992ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
29931731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2994ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
299587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2996ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2997883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2998ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2999ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
3000ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
3001768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
3002ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
3003ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
3004ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
3005ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
3006ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
30071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
300826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
30091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
301026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
3011bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
301287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
3013c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
301426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3015883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
301626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
301726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
3018bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
30190130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
3020cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
3021c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
3022c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
3023bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3024768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
302526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
302626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
30271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
302887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3029711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
303087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
3031e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3032711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
303387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
3034711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3035e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
303687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
303787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
303887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3039711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3040711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3041711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
304287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3043e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
3044768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
3045e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3046e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
3047768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
3048e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
3049f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
3050768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
305104633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
3052e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
3053768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
3054e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
305552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3056768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
305752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
3058414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
305987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
3060414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
30615cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
306287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3063414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
306487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3065414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3066414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3067414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
30685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3069414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
3070414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
3071414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
3072414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
3073414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
3074414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
307587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
307687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
3077414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
3078414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3079414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
3080768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
3081414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
3082e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
3083e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
3084e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
3085e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
3086e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
30871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
308856aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
3089768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3090f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
3091f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
3092711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
3093711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
3094711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3095711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3096831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
3097831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
3098831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
3099711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3100711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
3101711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3102ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
310355d3aaf9a537888734762170823daf750ea9036dEli Friedman
3104414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3105414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
3106711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
3107711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
3108711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
3109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
3110711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
3111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
3112414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
3113414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
3114414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
31155cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3116414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3117414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
3118414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
3119414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
3120414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3121414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
31225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3123414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
3124414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
3125414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3126414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
3127414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
3128414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
3129414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
3130414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
3131414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
31327530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("unexpected attribute kind");
3133711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3134711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3135711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3136711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3137711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
31381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
313987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3140711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3141711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
314287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
3143711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
3144711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
314587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
314687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
314787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
3148ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
3149ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
315055d3aaf9a537888734762170823daf750ea9036dEli Friedman
3151768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
3152711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
3153711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
3154711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
3155711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
315687c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
315787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
3158711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3159711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
316087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
316187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
316287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3163711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
3164711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
3165711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
316687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
316755d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
3168ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3169711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
317087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
317155d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
317287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3173711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
317455d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
317555d3aaf9a537888734762170823daf750ea9036dEli Friedman
3176bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (Context.getTargetInfo().getRegParmMax() == 0) {
317787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
317855d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
317987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3180711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
318155d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
318255d3aaf9a537888734762170823daf750ea9036dEli Friedman
3183711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
3184bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  if (numParams > Context.getTargetInfo().getRegParmMax()) {
318587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3186bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
318787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
3188711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
318955d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
319055d3aaf9a537888734762170823daf750ea9036dEli Friedman
3191711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
3192ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
3193ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
31941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
31957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
31967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
31977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
3198bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
3199bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
32007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
32017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
32027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
320387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
32047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3205883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
32067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
32077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
32087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
32097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
32107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
32117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
32127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
32137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
32147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
32157b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
32167b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
32177b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
32187b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
32197b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
32207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
32217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
32227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
32237b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
32247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
32257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
32267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
32277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
32287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
32297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
32307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
3231768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
32327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
32337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
32347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
32357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
32367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
32377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
32387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
32390744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
3240b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
3241b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
3242b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3243c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
32446c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
32456c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isObjCObjectPointerType() ||
32466c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         S.Context.isObjCNSObjectType(type);
3247c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3248c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
32496c73a2975ba9112787380abd878876336957b3f6Douglas Gregor  return type->isDependentType() ||
32506c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         type->isPointerType() ||
32516c73a2975ba9112787380abd878876336957b3f6Douglas Gregor         isValidSubjectOfNSAttribute(S, type);
3252c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3253c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
325587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
3256c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
325787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3258768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedParameter;
3259c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3260c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3261c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3262c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
326387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
3264c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3265c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3266c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
3267c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3268c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3269c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3270c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3271c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
327287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
3273768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << cf;
3274c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3275c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3276c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3277c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
3278768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
3279c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
3280768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
3281c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3282c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
32841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
328587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
328687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3287768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << ExpectedMethod;
3288c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
3289c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3290c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3291768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
3292c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
3293c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
32941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
32951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
3296b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3297c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
3298bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
329987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3300c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
330187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3302831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
33034e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
330487c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
3305f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
330687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3307c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
33085dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
330987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
3310768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis        << Attr.getRange() << Attr.getName()
3311883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
3312b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
3313b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
3314bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3315c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
3316c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
331787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
33187530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie  default: llvm_unreachable("invalid ownership attribute");
3319c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
3320c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
3321c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
3322c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
3323c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
3324c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3325c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3326c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
3327c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
3328c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
3329c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
3330c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
3331c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
3332c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3333c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
333487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3335768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
3336bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
33375dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
3338bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
333987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
3340b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
3341b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("invalid ownership attribute");
3342c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
3343768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
3344c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
3345c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
334631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
3347768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
3348f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
334931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
335031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
3351768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
3352f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
335331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
3354b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
3355768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
3356f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3357b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3358b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
3359768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
3360f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
3361b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
3362b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
3363b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
3364b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3365dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
3366dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
3367dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
3368dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3369dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
3370dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
337194d55d7ecdd693788a8f3910a0da1b5ecdaa8a86Fariborz Jahanian  if (!method) {
33720e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3373f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
3374dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3375dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3376dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3377dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
3378dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
3379f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian
3380f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian  if (!resultType->isReferenceType() &&
3381f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
3382dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
3383dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
3384dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
3385dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3386dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
3387dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
3388dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
3389dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3390dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
3391768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
3392dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
3393dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
33948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer.
33958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
33968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (!isa<FunctionDecl>(D)) {
33978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3398f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << A.getRange() << A.getName() << ExpectedFunction;
33998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
34008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
34018dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
34028dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer);
34038dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
34048dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // Check whether there's a conflicting attribute already present.
34058dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  Attr *Existing;
34068dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
34078dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFUnknownTransferAttr>();
34088dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
34098dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    Existing = D->getAttr<CFAuditedTransferAttr>();
34108dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
34118dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (Existing) {
34128dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
34138dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getName()
34148dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
34158dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      << A.getRange() << Existing->getRange();
34168dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    return;
34178dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
34188dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
34198dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  // All clear;  add the attribute.
34208dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  if (IsAudited) {
34218dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
34228dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
34238dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  } else {
34248dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    D->addAttr(
34258dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
34268dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  }
34278dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall}
34288dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3429fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
3430fe98da0fa352462c02db037360788748f95466f7John McCall                                const AttributeList &Attr) {
3431fe98da0fa352462c02db037360788748f95466f7John McCall  RecordDecl *RD = dyn_cast<RecordDecl>(D);
3432fe98da0fa352462c02db037360788748f95466f7John McCall  if (!RD || RD->isUnion()) {
3433fe98da0fa352462c02db037360788748f95466f7John McCall    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3434f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedStruct;
3435fe98da0fa352462c02db037360788748f95466f7John McCall  }
3436fe98da0fa352462c02db037360788748f95466f7John McCall
3437fe98da0fa352462c02db037360788748f95466f7John McCall  IdentifierInfo *ParmName = Attr.getParameterName();
3438fe98da0fa352462c02db037360788748f95466f7John McCall
3439fe98da0fa352462c02db037360788748f95466f7John McCall  // In Objective-C, verify that the type names an Objective-C type.
3440fe98da0fa352462c02db037360788748f95466f7John McCall  // We don't want to check this outside of ObjC because people sometimes
3441fe98da0fa352462c02db037360788748f95466f7John McCall  // do crazy C declarations of Objective-C types.
34424e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (ParmName && S.getLangOpts().ObjC1) {
3443fe98da0fa352462c02db037360788748f95466f7John McCall    // Check for an existing type with this name.
3444fe98da0fa352462c02db037360788748f95466f7John McCall    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
3445fe98da0fa352462c02db037360788748f95466f7John McCall                   Sema::LookupOrdinaryName);
3446fe98da0fa352462c02db037360788748f95466f7John McCall    if (S.LookupName(R, Sc)) {
3447fe98da0fa352462c02db037360788748f95466f7John McCall      NamedDecl *Target = R.getFoundDecl();
3448fe98da0fa352462c02db037360788748f95466f7John McCall      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
3449fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
3450fe98da0fa352462c02db037360788748f95466f7John McCall        S.Diag(Target->getLocStart(), diag::note_declared_at);
3451fe98da0fa352462c02db037360788748f95466f7John McCall      }
3452fe98da0fa352462c02db037360788748f95466f7John McCall    }
3453fe98da0fa352462c02db037360788748f95466f7John McCall  }
3454fe98da0fa352462c02db037360788748f95466f7John McCall
3455fe98da0fa352462c02db037360788748f95466f7John McCall  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
3456fe98da0fa352462c02db037360788748f95466f7John McCall                                             ParmName));
3457fe98da0fa352462c02db037360788748f95466f7John McCall}
3458fe98da0fa352462c02db037360788748f95466f7John McCall
34591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
34601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
346187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
3462f85e193739c953358c865005855253af4f68a497John McCall
346387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3464f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    << Attr.getRange() << Attr.getName() << ExpectedVariable;
3465f85e193739c953358c865005855253af4f68a497John McCall}
3466f85e193739c953358c865005855253af4f68a497John McCall
34671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
34681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
346987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
347087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
3471f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor      << Attr.getRange() << Attr.getName() << ExpectedVariable;
3472f85e193739c953358c865005855253af4f68a497John McCall    return;
3473f85e193739c953358c865005855253af4f68a497John McCall  }
3474f85e193739c953358c865005855253af4f68a497John McCall
347587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
3476f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
3477f85e193739c953358c865005855253af4f68a497John McCall
3478f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
3479f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
348087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
3481f85e193739c953358c865005855253af4f68a497John McCall      << type;
3482f85e193739c953358c865005855253af4f68a497John McCall    return;
3483f85e193739c953358c865005855253af4f68a497John McCall  }
3484f85e193739c953358c865005855253af4f68a497John McCall
3485f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
3486f85e193739c953358c865005855253af4f68a497John McCall
3487f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
3488f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
3489f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
3490f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
3491f85e193739c953358c865005855253af4f68a497John McCall
3492f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
3493f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
3494f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
3495f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
3496f85e193739c953358c865005855253af4f68a497John McCall    break;
3497f85e193739c953358c865005855253af4f68a497John McCall
3498f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
3499f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
3500f85e193739c953358c865005855253af4f68a497John McCall    break;
3501f85e193739c953358c865005855253af4f68a497John McCall
3502f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
3503f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
350487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
3505f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
3506f85e193739c953358c865005855253af4f68a497John McCall    break;
3507f85e193739c953358c865005855253af4f68a497John McCall  }
3508f85e193739c953358c865005855253af4f68a497John McCall
350987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
3510768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
3511f85e193739c953358c865005855253af4f68a497John McCall}
3512f85e193739c953358c865005855253af4f68a497John McCall
3513f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
35149428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  switch (Attr.getKind()) {
35159428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  default:
35169428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return false;
35179428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllimport:
35189428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_dllexport:
35199428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_uuid:
35209428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_deprecated:
35219428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noreturn:
35229428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_nothrow:
35239428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_naked:
35249428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  case AttributeList::AT_noinline:
35259428772f16e379bcad35254251f96e3d1077c730Aaron Ballman    return true;
35269428772f16e379bcad35254251f96e3d1077c730Aaron Ballman  }
352711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
352811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
352911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
353011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
353111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
353211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
35331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
353462ec1f2fd7368542bb926c04797fb07023547694Francois Pichet  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
353511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
35361731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
353711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
35381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
353911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
354011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
35415cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
3542d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3543d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
3544d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3545d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3546d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
35475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
3548d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3549d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
3550d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
3551f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor
3552d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
3553d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
3554d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3555d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3556d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3557d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
3558d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3559d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
3560d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
3561d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
3562f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
3563d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
35645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
3565f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
3566f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
3567f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
3568f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
3569d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
3570d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
3571d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3572d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
3573d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
3574d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
3575d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
3576d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
3577d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3578d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3579d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
358011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
3581768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
358211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3583d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
358411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3585f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3586f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3587b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
35880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
35890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
35900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
35911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
35921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
359360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
35941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
35951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
35961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
359760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
359860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
359960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
360060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3601e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
36021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
36031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3604803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
3605e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_ibaction:            handleIBAction(S, D, Attr); break;
3606e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutlet:          handleIBOutlet(S, D, Attr); break;
3607e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han    case AttributeList::AT_iboutletcollection:
36081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3609803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3610207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3611ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
36126e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
36134211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
36144211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3615bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3616bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3617803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
361860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
361960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
362060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
362160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
362260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
362360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
36241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
36251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3626bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
36271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3628b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
36291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
36301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
36311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3632bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
36331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
36341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
36351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
36361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
36371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
36381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
36393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
36401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
36413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
36421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
36431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
36441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
36451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
36467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
36471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
36487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
36491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
36501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
36511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
36521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
36531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3654dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3655dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3656dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
36571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
36581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
36591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
36601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
36611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
36621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3663b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3664b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
36651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3666f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
36671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3668f85e193739c953358c865005855253af4f68a497John McCall
3669dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3670dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3671dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3672fe98da0fa352462c02db037360788748f95466f7John McCall  case AttributeList::AT_ns_bridged:
3673fe98da0fa352462c02db037360788748f95466f7John McCall    handleNSBridgedAttr(S, scope, D, Attr); break;
3674fe98da0fa352462c02db037360788748f95466f7John McCall
36758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_audited_transfer:
36768dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall  case AttributeList::AT_cf_unknown_transfer:
36778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall    handleCFTransferAttr(S, D, Attr); break;
36788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall
3679b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3680c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
36811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3682c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
36831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3684c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3685c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
368631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
368731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3688b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3689b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
36901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3691b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3692e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_reqd_work_group_size:
36931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
36946f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3695521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
36961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3697521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
36981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
3699e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_ms_struct:    handleMsStructAttr    (S, D, Attr); break;
37001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
37011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3702e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_objc_arc_weak_reference_unavailable:
3703742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3704742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
3705b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard  case AttributeList::AT_objc_root_class:
3706b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    handleObjCRootClassAttr(S, D, Attr);
3707b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard    break;
370871207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  case AttributeList::AT_objc_requires_property_definitions:
370971207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
3710e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian    break;
37111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
3712f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola  case AttributeList::AT_returns_twice:
3713f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    handleReturnsTwiceAttr(S, D, Attr);
3714f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola    break;
37151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
37161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
37171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3718026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
37191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
37201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
37211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3722803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
37231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3724803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
37250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
37261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
37270db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3728d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
37291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3730d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
3731e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han  case AttributeList::AT_NSObject:    handleObjCNSObject    (S, D, Attr); break;
37321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
37331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
37341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
37351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
37361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
37371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
37381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
37391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3740bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
374105f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
374205f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
37437255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
37441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
37457255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
374604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
374704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
374804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3749f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
375052fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3751414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
37521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
375304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3754f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
37551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3756f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
375711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
37581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
375911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3760fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3761fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3762fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3763fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3764fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3765fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3766fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3767fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3768fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3769fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3770fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
377171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany  case AttributeList::AT_no_address_safety_analysis:
377271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    handleNoAddressSafetyAttr(S, D, Attr);
377371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany    break;
3774fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3775fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3776fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3777fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3778fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3779fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3780db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_guarded_by:
3781db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr);
3782db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3783db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_pt_guarded_by:
3784db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleGuardedByAttr(S, D, Attr, /*pointer = */true);
3785db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3786db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_lock_function:
3787db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr, /*exclusive = */true);
3788db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3789db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_locks_required:
3790db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true);
3791db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3792db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_exclusive_trylock_function:
3793db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr, /*exclusive = */true);
3794db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3795db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_lock_returned:
3796db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockReturnedAttr(S, D, Attr);
3797db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3798db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_locks_excluded:
3799db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksExcludedAttr(S, D, Attr);
3800db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3801db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_lock_function:
3802db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLockFunAttr(S, D, Attr);
3803db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3804db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_locks_required:
3805db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleLocksRequiredAttr(S, D, Attr);
3806db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3807db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_shared_trylock_function:
3808db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleTrylockFunAttr(S, D, Attr);
3809db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3810db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_unlock_function:
3811db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleUnlockFunAttr(S, D, Attr);
3812db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3813db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_before:
3814db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */true);
3815db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3816db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski  case AttributeList::AT_acquired_after:
3817db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    handleAcquireOrderAttr(S, D, Attr, /*before = */false);
3818db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski    break;
3819fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3820803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
382182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
382282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
382382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
38247d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
38257d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3826803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3827803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3828803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3829803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
383060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
383160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
383260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
383360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
38341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
38351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
383660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
383760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
383860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
383960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
384060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
384160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
384260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
384360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
384460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
38451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
384660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
384760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
38481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
384960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
385060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3851803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3852803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3853f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
385460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
385560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
385611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
38571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
385811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
385911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
386011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
386111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
386211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
386360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
386411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3865dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
386611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3867803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3868803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3869803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
38705f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access
38715f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier.
38725f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
38735f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          const AttributeList *AttrList) {
38745f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
38755f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    if (l->getKind() == AttributeList::AT_annotate) {
38765f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      handleAnnotateAttr(*this, ASDecl, *l);
38775f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    } else {
38785f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
38795f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      return true;
38805f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    }
38815f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  }
38825f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
38835f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  return false;
38845f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen}
38855f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
3886e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it
3887e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about.
3888e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
3889e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for ( ; A; A = A->getNext()) {
3890e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    // Only warn if the attribute is an unignored, non-type attribute.
3891e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->isUsedAsTypeAttr()) continue;
3892e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
3893e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3894e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    if (A->getKind() == AttributeList::UnknownAttribute) {
3895e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
3896e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3897e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    } else {
3898e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
3899e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall        << A->getName() << A->getRange();
3900e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    }
3901e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  }
3902e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3903e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3904e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being
3905e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes
3906e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it.
3907e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
3908e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
3909e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  ::checkUnusedDeclAttributes(*this, D.getAttributes());
3910e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
3911e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
3912e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall}
3913e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall
3914e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3915e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
3916900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
3917900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                      SourceLocation Loc) {
39187b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3919e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3920e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3921900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    FunctionDecl *NewFD;
3922900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Missing call to CheckFunctionDeclaration().
3923900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Mangling?
3924900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the qualifier info correct?
3925900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // FIXME: Is the DeclContext correct?
3926900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3927900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 Loc, Loc, DeclarationName(II),
3928900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->getType(), FD->getTypeSourceInfo(),
3929900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 SC_None, SC_None,
3930900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isInlineSpecified*/,
3931900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 FD->hasPrototype(),
3932900693b715b3832a42ae87157332baece94ccdd8Eli Friedman                                 false/*isConstexprSpecified*/);
3933900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NewD = NewFD;
3934900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3935900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (FD->getQualifier())
3936c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3937900693b715b3832a42ae87157332baece94ccdd8Eli Friedman
3938900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // Fake up parameter variables; they are declared as if this were
3939900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    // a typedef.
3940900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    QualType FDTy = FD->getType();
3941900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
3942900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      SmallVector<ParmVarDecl*, 16> Params;
3943900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
3944900693b715b3832a42ae87157332baece94ccdd8Eli Friedman           AE = FT->arg_type_end(); AI != AE; ++AI) {
3945900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
3946900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Param->setScopeInfo(0, Params.size());
3947900693b715b3832a42ae87157332baece94ccdd8Eli Friedman        Params.push_back(Param);
3948900693b715b3832a42ae87157332baece94ccdd8Eli Friedman      }
39494278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie      NewFD->setParams(Params);
3950b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3951e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3952e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3953ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3954a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
395516573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
395616573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3957b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3958b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3959c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3960b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3961e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3962e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3963e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3964e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3965e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3966e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
39677b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3968c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3969c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3970c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3971c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3972900693b715b3832a42ae87157332baece94ccdd8Eli Friedman    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
3973cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3974cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3975cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3976c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3977c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3978c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3979c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3980c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3981c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3982c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3983c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3984cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3985e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3986e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3987e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
39880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
39890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
39900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
399160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
399260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3993d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3994d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
399531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
399631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
399731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
399831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
399931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
400031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
400131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
400231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
400331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
400431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
400531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
400631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
4007d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
4008e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
4009e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
4010e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
4011e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
40120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
40137f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
401460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4015bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
40160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
40170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
40180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
40190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
40200744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
40210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
402260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
4023bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
40240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
40250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
402660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
40270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
402854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4029f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
4030f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
4031f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
4032f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
4033f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
4034a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  // Function declarations in sys headers will be marked unavailable.
4035a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
4036a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian      !isa<FunctionDecl>(decl))
4037f85e193739c953358c865005855253af4f68a497John McCall    return false;
4038f85e193739c953358c865005855253af4f68a497John McCall
4039f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
4040f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
4041f85e193739c953358c865005855253af4f68a497John McCall}
4042f85e193739c953358c865005855253af4f68a497John McCall
4043f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
4044f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4045f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
4046f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
4047f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
4048f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
4049f85e193739c953358c865005855253af4f68a497John McCall    return;
4050f85e193739c953358c865005855253af4f68a497John McCall  }
40514e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (S.getLangOpts().ObjCAutoRefCount)
4052175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
4053175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // FIXME. we may want to supress diagnostics for all
4054175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      // kind of forbidden type messages on unavailable functions.
4055175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      if (FD->hasAttr<UnavailableAttr>() &&
4056175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag.getForbiddenTypeDiagnostic() ==
4057175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian          diag::err_arc_array_param_no_ownership) {
4058175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        diag.Triggered = true;
4059175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian        return;
4060175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian      }
4061175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian    }
4062f85e193739c953358c865005855253af4f68a497John McCall
4063f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4064f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4065f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
4066f85e193739c953358c865005855253af4f68a497John McCall}
4067f85e193739c953358c865005855253af4f68a497John McCall
4068eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
4069eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
4070eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
4071eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
4072eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4073eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
4074eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
4075eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
4076eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
4077eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
4078eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4079eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
4080eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
4081eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4082eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
4083eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
4084eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
4085eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
4086eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
4087eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
4088eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
408954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
409054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4091eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
4092eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
4093eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
409454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4095eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
4096eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
4097eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
4098eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
409954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4100eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
4101eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
410254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
4103eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
4104eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
4105eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
410658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
41072f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
41082f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
4109e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall  if (decl) {
4110eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
4111eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
41122f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
41132f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
41142f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
41152f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
41162f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
4117eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
4118eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
4119eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
41202f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
41212f514480c448708ec382a684cf5e035d3a827ec8John McCall
4122eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
41232f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
4124e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        // Don't bother giving deprecation diagnostics if the decl is invalid.
4125e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall        if (!decl->isInvalidDecl())
4126e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall          S.HandleDelayedDeprecationCheck(diag, decl);
41272f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
41282f514480c448708ec382a684cf5e035d3a827ec8John McCall
41292f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
4130eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
41312f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
4132f85e193739c953358c865005855253af4f68a497John McCall
4133f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
4134f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
4135f85e193739c953358c865005855253af4f68a497John McCall        break;
413654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
413754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
413854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
413954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
414058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
4141eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
414229233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
414358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
4144eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
41452f514480c448708ec382a684cf5e035d3a827ec8John McCall}
41462f514480c448708ec382a684cf5e035d3a827ec8John McCall
41472f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
41482f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
41490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
41502f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
4151c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    // A category implicitly has the availability of the interface.
4152c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
4153c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis      return CatD->getClassInterface()->isDeprecated();
41542f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
41552f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
41562f514480c448708ec382a684cf5e035d3a827ec8John McCall}
41572f514480c448708ec382a684cf5e035d3a827ec8John McCall
41589c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
41592f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
41602f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
41612f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
41622f514480c448708ec382a684cf5e035d3a827ec8John McCall
41632f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
4164ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
4165c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
4166ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
4167ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
4168b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  else if (DD.getUnknownObjCClass()) {
4169b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_fwdclass_message)
4170b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian      << DD.getDeprecationDecl()->getDeclName();
4171b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class);
4172b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  }
4173c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
4174c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
4175ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
417654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
417754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
41785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
41798e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
418089ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
418154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
4182eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
4183b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
4184b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              UnknownObjCClass,
4185b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian                                                              Message));
418654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
418754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
418854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
418954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
41903a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
419154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
4192ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
4193c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
4194c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
41958e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
4196743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
41978e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
419889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
41998e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
420089ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
420189ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
42028e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
420354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
4204