SemaDeclAttr.cpp revision 31e37b2d7b4815fdea6a35d49f33005562f0d494
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"
18acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
20f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h"
21fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2219510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
239c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
24797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
269c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of
29883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
30883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCallenum {
31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunction,
32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedUnion,
33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableOrFunction,
34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionOrMethod,
35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameter,
36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameterOrMethod,
37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrBlock,
38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassOrVirtualMethod,
39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrParameter,
40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClass,
41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVirtualMethod,
42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassMember,
43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariable,
44883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedMethod,
45883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableFunctionOrLabel
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
1971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
1981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth                                  unsigned int Num) {
1991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (Attr.getNumArgs() != Num) {
2001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    return false;
2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  }
2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  return true;
2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth}
2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
207fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
208fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var
209fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable
210fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
211fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic bool mayBeSharedVariable(Decl *D) {
212fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (isa<FieldDecl>(D))
213fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return true;
214fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if(VarDecl *vd = dyn_cast<VarDecl>(D))
215fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
216fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
217fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
218fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
219fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
220fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
221fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type.
222fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message.
223fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise
224fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski///
225fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskibool checkIsPointer(Sema & S, Decl * D, const AttributeList & Attr) {
226fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if(ValueDecl * vd = dyn_cast <ValueDecl>(D)) {
227fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    QualType QT = vd->getType();
228fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    if(QT->isAnyPointerType()){
229fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      return true;
230fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    }
231fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_pointer_attribute_wrong_type)
232fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName()->getName() << QT;
233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  } else {
234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
235fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName();
236fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
237fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  return false;
238fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
239fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
240e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
241e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
242e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
243e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
2443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
2453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
2463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
2473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
248fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr,
249fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                 bool pointer = false) {
250fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
251fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
252fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
253fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
254fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
255fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // D must be either a member field or global (potentially shared) variable.
256fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!mayBeSharedVariable(D)) {
257fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
258fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << 15; /*fields and global vars*/;
259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
262fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer && !checkIsPointer(S, D, Attr))
263fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
264fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
265fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (pointer)
266fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getLoc(), S.Context));
267fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
268fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getLoc(), S.Context));
269fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
270fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
271fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr,
272fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                               bool scoped = false) {
273fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
274fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
275fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
276fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
277fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
278fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isa<CXXRecordDecl>(D)) {
279fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
280fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedClass;
281fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
282fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
283fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
284fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (scoped)
285fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getLoc(), S.Context));
286fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  else
287fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    D->addAttr(::new (S.Context) LockableAttr(Attr.getLoc(), S.Context));
288fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
289fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
290fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D,
291fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                     const AttributeList &Attr) {
292fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  assert(!Attr.isInvalid());
293fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
294fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!checkAttributeNumArgs(S, Attr, 0))
295fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
296fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
297fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  if (!isFunction(D)) {
298fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
299fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski      << Attr.getName() << ExpectedFunctionOrMethod;
300fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    return;
301fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  }
302fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
303fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getLoc(),
304fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski                                                          S.Context));
305fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski}
306fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
3081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
30987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
310545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
311803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
312545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
3136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
314bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
3169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
3179cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
3189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
3199cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
3209cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
321f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
322f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
323f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
3244ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
3254ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
3264ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
3274ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
3284ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
3294ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
3309cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
3319cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
3321731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
3339cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
3341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
3357a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
3366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3379cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
3389cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
3399cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
3409ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
3419cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
342ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
343a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
344bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3459cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
3469cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
3476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
3521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
3536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
354bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
35587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
356cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
35787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
3586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
3596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
3606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
361803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
362fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
36308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
3646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
365cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
3666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
3673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
3686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
37187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
372c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getLoc(), S.Context));
373c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
374c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
375c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
376c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
3771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
37896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
3791731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
38096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
381bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
38263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
38387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
38463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
38587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
38663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
38763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
38863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
3894ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
39063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
39163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
3921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
39363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
3941731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
39563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
39663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
39763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
398efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
39987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D)) {
40087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
40163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
402efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
40363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
4044ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
40596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
40696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
4071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
4081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
409857e918a8a40deb128840308a318bf623d68295fTed Kremenek
410857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
411a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
412857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
413857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
414857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
415857e918a8a40deb128840308a318bf623d68295fTed Kremenek
416857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
417857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
41887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!(isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
4194ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
420857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
421857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
42287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
4233a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
4243a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
4253a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
4263a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
4273a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
42887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
4293a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
4303a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
4313a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
4323a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
4333a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
4343a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
435a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
436a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
437a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
4383a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
439b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
44087c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
441a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
442a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
443a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
444a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
445b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
446a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
447a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
448a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
449a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
450a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
451a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
452a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
453a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
454a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
45587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
456cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
457857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
458857e918a8a40deb128840308a318bf623d68295fTed Kremenek
459d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
46068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
46168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
46268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
46368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
46468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
46568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
46668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
46768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
46868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
46968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
47068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
47168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
47268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
47368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
4741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
475bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
476bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
47787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
478fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
479883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
480eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
481eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
482bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
48307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
48407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
48587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
48687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
487eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
488eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
4895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> NonNullArgs;
490bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
491eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
492eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
493bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
494bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
495eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
4967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
497eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
498ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
499ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
500fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
501fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
502eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
503eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
504bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
505eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
506bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
507eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
508fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
50930bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
510eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
511eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
512bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
513465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
51407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
51507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
51607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
51707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
51807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
51907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
52007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
52107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
52207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
523eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
524eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
52587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
526d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
52768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
528dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
529eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
530c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
531fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
5327fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
533eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
534bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
535eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
536eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
537bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
538bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
539bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
5407fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
54187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
54287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
543d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
544dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
545d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
54646bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
547bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
548ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
54960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
55060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
55160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
55260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
55360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
5547fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
55560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
556eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
5577fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
5587fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
5597fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
560dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
56187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
562cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
563eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
564eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
5651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
566dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
567dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
568dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
570dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
571dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
5722a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
5732a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
574dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
575dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
576dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
577dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
578dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
579dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
580dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
581cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
5822a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
5832a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
584cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
585dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
586dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
587dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
588dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
5902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
591cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
592dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
593dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
594dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
595dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5962a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
5972a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
598cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
599dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
600dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
601dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
602dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
603dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
6042a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
6052a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
6062a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
6072a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
608dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
609dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
61087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
611883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
612883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
613dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
614dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
615dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
61607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
61707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
61887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
61987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
620dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
6215f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Module = AL.getParameterName()->getName();
622dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
623dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
624dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
625dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
626dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
6275f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<unsigned, 10> OwnershipArgs;
628dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
6292a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
6302a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
631dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
6327a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
633dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
634dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
635dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
636dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
637dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
638dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
639dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
640dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
641dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
642dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
643dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
644dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
645dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
646dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
647dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
648dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
64907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
65007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
65107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
65207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
65307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
65407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
65507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
65607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
65707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
658dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
659cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
660cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
661dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
66287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
663dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
664dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
665dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
666cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
667dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
668dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
669dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
670dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
671dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
672dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
673cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
674dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
675dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
6767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
677dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
678dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
679dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
680dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
681dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
682dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
683dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
684dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
685dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
686dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
687dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
6882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
6892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
690dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
691dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
692dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
693cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
69487c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
69587c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
696cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
697cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
698cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
699cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
700cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
701cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
702cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
703dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
704dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
705dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
706dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
707dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
708dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
709dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
710dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
711dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
712dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
713cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
714cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
715cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
716cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
717dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
718cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
71987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
720cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
721dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
722dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
723332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
724332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
725332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
726332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
727332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
728332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
729332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
730332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
731332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
732332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
733332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
734332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
735332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
736332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
737332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
738332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
739332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
74011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
74111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
74211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
7431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
74411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
74511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
74611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
74711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
74811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
74911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
75087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
751332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
752883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
753332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
754332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
755332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
75687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
757332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
75811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
75911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
76011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
76111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
76211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
76311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
76411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
76511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
76611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
76711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
76887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
7697a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
7707a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
771332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
7727a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
77311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
77411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
77511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
77611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
77711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
77811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
77911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
78011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
78111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
78211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
78311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
78411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
78511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
78611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
78711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
78811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
78911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
79011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
79111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
79211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
793332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
794332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
79511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
79611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
79711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
79811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
79911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
80011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
80111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
80211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
8037a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
80411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
80511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
80611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
8075cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
80811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
80911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
81011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
81111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
81211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
81311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
81487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
815f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
81611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
81711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
81887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
81911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
82011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
8211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
8226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
823545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
8243c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
8256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
827bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
8287a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
8296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
8306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
831bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
8325cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
833fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
8343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
8356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
837bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
838db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar  if (S.Context.Target.getTriple().isOSDarwin()) {
839f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
840f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
841f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
842f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
8436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
844bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
84587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
846f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
8476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
850dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
8511731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
852dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
853dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
85487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
855dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
856883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
857dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
858dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
859dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
86087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
861dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
862dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
8631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
8641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
865dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
866831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
8673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
868af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
869af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
8705bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
87187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
8725bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
873883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
8745bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
8755bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
876bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
87787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
878af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
879af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
8801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
881dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
882831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
88376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
88476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
88576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
8861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
88787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
8892cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
89087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
8912cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
8922cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
893fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
894fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
8952cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
89676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
89776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
8981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
89934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
9001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
90134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
90234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
90387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
90434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
90534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
9061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
90756aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
90887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
90987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
910722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
911722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
912883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
913a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
914a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
9151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
91656aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
91787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
91887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
919722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
920722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
921883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
922a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
923a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
9241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
92587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
926711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
927711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
928711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
92987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
930711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
931883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
932711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
933711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
934711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
93587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
936711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
937711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
938711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
939831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
940711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
941711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
942711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
943711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
944711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
945711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
946b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
947b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
9481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
9491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
950b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
951b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
952b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
953b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
9541731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
9551731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
956b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
95787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
95887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
9593ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
9603ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
961e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
962e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
963b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
964883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
965b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
96619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
9676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
968b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
96987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
9706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
97235cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
9731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
97435cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
97535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
97635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
977f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
978f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
979f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
980f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
981f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
98235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
98335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
98435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
98535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
98635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
98735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
98835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
98935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
99035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
99135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
99235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
99335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
99435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
99535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
99635cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
99787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
99835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
999883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
100035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
100135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
100235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
100387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
100435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
100535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
100635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
100735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
100887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
100901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
101001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
101101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
101201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
101301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
101401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
101501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
101601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
101701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
101801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
101901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
102001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
1021f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
1022f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
102301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
102401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
102501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
102601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
102701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
102801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
102901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
103087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
103135cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
103235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
10331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
103487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
1035bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1036883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1037bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
1038bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1039bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
1040bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1041bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
10421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
104373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
1044831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
10453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
104673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
104773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1048bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
104987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
105087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
1051fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1052883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
105373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
105473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
1055bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
105687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
105773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
105873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
10591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1060b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
1061831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
1062b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1063b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1064b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1065bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
106687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1067186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
1068b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1069b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
1070b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
107187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
1072b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1073883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
1074b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
1075b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
1076bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
107787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
1078b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
1079b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
10801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
10813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1082bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1083bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
10843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1085bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
10863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
10883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
10897a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
10903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1091ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1092ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1093fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
10953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
10963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
10973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
10983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1099bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
110087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1101fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1102883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
11033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
11043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
11053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
110687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
1107f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
11083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
11093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
11101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
11113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1112bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1113bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
11143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1115bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
11163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
11173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
11183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
11197a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
11203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1121ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1122ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1123fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11243c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
11253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
11263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
11273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
11283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1129bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
113087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1131fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1132883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
11333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
11343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
11353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
113687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1137f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
11383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
11393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
11401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1141951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1142951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1143bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1144c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1145c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1146951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1147c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
11485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1149951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1150951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1151c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1152951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1153951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1154c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1155c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1156951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
11576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1158bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
115987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
11606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1163951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1164951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1165bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1166bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1167bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1168951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1169c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
11705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str;
1171951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1172951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1173c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1174951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1175c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1176c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1177c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1178951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1179c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
118087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
1181bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1182bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1183742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1184742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1185742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1186742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1187742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1188742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1189742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1190742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1191742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1192742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                          Attr.getLoc(), S.Context));
1193742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1194742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
11951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
11961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
11970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
11980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
11990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
12005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef PlatformName
12010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
12020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
12030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
12040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
12050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
12060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
12070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
12080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
12090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
12100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
12110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1212b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
12130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
12140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // Ensure that Introduced < Deprecated < Obsoleted (although not all
12150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
12160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
12170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Deprecated.Version)) {
12180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
12190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
12200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
12210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
12220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
12230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
12240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
12250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Obsoleted.Version)) {
12260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
12270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
12280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
12290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
12300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
12310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
12320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
12330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Deprecated.Version < Obsoleted.Version)) {
12340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
12350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
12360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
12370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
12380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
12390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
124087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
12410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
12420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
12430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1244b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1245b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                IsUnavailable));
12460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
12470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
12481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
12496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
12501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
12516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1252bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12537a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
12546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
12556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1256bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12575cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!Str || !Str->isAscii()) {
1258fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
12606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1262bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef TypeStr = Str->getString();
1264cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1265bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1266c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1267cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1268c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1269cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1270c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1271cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1272c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1273cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
12746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
127508631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
12766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1278bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
127987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
12806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
12831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1284d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1285d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
128687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1287883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1288d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1289d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1290d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
129187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
129287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
129387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1294d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1295d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
129687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1297d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
129887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1299d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1300d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1301d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
13025f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef param = Attr.getParameterName()->getName();
1303d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1304d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1305d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1306d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1307d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1308d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1309d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1310d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1311d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1312d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1313d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1314d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1315d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1316d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1317d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1318d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
131987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1320d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1321d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1322d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1323f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1324f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1325f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1326f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1327f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1328f85e193739c953358c865005855253af4f68a497John McCall    return;
1329f85e193739c953358c865005855253af4f68a497John McCall  }
1330f85e193739c953358c865005855253af4f68a497John McCall
133187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getLoc(),
1332f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1333d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1334d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
13351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
13361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
13371731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
13380db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1339bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13400db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
13410db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
13420db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
13430db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
13440db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1345bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1346cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
13470db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
13480db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
13491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1350fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
13512b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1352fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1353fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1354162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1355fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1356fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
13576217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1358fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1359fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1360fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1361fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1362cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1363fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1364fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1365bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
13661b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1367f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
13682b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1369f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1370f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1371f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1372f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1373f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1374f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1375f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1376f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1377cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1378f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1379f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
13801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1381bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1382fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
13833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
13849eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
13859eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1386bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
13883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
13899eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
13909eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1391bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1392cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
139392e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
13949eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
13959eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1396fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
13973c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
13989eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
13999eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1400bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
140187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
14029eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
14039eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
14041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1405770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1406770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1407bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1408770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1409bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1410bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1411770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1412770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
14137a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1414770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1415ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1416ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1417fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1419770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1420770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1421770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1422bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1423770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1424fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1425fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1426770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1427770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1428770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1429770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1430770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1431770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
14327a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1433770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1434ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1435ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1436fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
14373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1438770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1439770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1440770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1441bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1442770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1443770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1444770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1445fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1446fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1447770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1448770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1449770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1450770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
145187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1452183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1453897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1454bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1455897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1456897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1457897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1458897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1459bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1460897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
14613bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1462770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1463bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
146487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1465770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
14663bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1467770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
14682f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
146987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (isa<BlockDecl>(D)) {
1470bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1471bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
14722f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
147387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
14742f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1475daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
147687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1477f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
14782f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
14793bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
14803bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
14812f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
14822f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1483ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
14842f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1485883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
14862f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
14872f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1488770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1489fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1490883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1491770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1492770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
149387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1494f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1495770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1496770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
14971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1498026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
14991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1500026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1501026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1502f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1503026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1504883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1505026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1506026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1507bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1508f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1509f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1510f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1511f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1512f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1513f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1514f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1515f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1516f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1517f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1518f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1519f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1520cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1521026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1522026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
15231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
152587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
152687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
15276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
15296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
153087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
153187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
153287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1533f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1534f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1535f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
153687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1537332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1538332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1539332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
154087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
15416e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
15426e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1543bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
154487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  nd->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
15456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
15491731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
15506e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
15511731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
15526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
15536e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
15546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
15550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
15560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
15570a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
15580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
15590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
1560def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1561db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar             (S.Context.Target.getTriple().isOSDarwin() &&
1562def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor              isa<ObjCInterfaceDecl>(D))) {
1563def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
1564def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
1565c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1566883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
15676e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
15686e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
15696e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
15706e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1571cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
15726e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
15736e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
15741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
15751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
15766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
15771731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
15786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
15796f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
15806f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
15816f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
15827a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
15836f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1584ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1585ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
15866f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
15876f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
15886f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
15896f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
15906f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
15916f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1592cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1593cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
15946f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
15956f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
15966f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
15971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
159817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
15991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
160017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
160117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
160217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
160317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
16047a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1605797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
160617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1607797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
160817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
160917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
16101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1611797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1612bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1613a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1614a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1615a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1616797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1617797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
16181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1619a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1620a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1621a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1622a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1623a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1624a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1625f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1626f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
162717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
162817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
16296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1632831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
16333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
16346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1636b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
163787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
1638b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
1639b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      Existing->setLocation(Attr.getLoc());
1640b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
164187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
1642b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
16436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
16446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1646232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1647831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
16483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1649232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1650232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1651bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
165287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
1653b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
1654b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor     Existing->setLocation(Attr.getLoc());
1655b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
165687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1657b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
1658232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1659232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
16601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1661232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
16621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1663232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1664bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
166587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1666232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1667232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
16681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1669bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1670f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1671f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1672f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1673bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1674f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1675f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1676f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1677f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1678bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
167987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
1680bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1681f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1682f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1683f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1684f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1685bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1686f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1687c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1688f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1689f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1690f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1691f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
1692f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1693f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1694f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1695f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1696bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1697f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1698f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
1699f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1700f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
1701f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1702f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1703f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1704f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1705f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
1706f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1707f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
1708f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1709f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1710f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1711bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
171289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
171389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
171489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
171589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1716b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
1717b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
1718f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
171989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
172089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
172189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
172289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1723bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
172487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1725223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1726f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1727f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1728bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1729bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
17301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
17311731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
17325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
17331731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
173487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
17355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1736883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
17375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
17385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
173907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
174007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
174107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
174287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
174387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
17445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
174507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
17465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
17477a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
17485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1749ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1750ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
17515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
17525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
17535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
17545b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1755bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
17575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
17585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
17595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
17605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1761bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1763bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
176407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
176507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
176607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
176707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
176807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
176907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
177007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
177107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
177207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
17735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
177487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
1775bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17765b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
17775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
17785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
17795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
17806217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
17815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
17825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1783bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
17845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
17855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1786bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
178787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
17885b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
17895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
17905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
17916217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
17925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
17935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1794bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
17955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
17965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1797bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1798bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
179987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
180007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
18015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
18025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
18032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
18042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
18052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
18062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
18072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
18083c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
18092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
18102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
18112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
18122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
18132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
18145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
18152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
18162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
18172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
18182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
18192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
18202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
18212b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
18222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
18232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
18242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
18252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
18262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
1827cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
1828cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
18292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
18302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1831bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1832bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
18333c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
18343c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
18352b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
18362b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
18372b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1838521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
1839521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
18401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
18411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1842521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
1843521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1844521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1845521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1846521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
184787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
1848b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1849b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1850b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1851b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
185287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
1853b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
1854b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
1855b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
1856b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1857b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1858b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1859b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1860b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1861521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
1862521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1863521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1864521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1865521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
18667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
1867b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1868521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
1869521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1870521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1871521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1872521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
1873521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1874521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1875521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
18769f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
1877521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
1878521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1879521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
1880521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1881521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1882521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
188387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
1884f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
1885521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
1886521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1887bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1888bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
18891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1891545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1892fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
18933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
18946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1897545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
18983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
18996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
190287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
1903fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1904883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
19056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
190807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
190907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
191087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
191187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
19126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
19136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Format = Attr.getParameterName()->getName();
19156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
19172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
19182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
19192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
19202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
19212b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
19223c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
19233c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
19243c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
19253c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
19262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1927fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
192801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
19296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
19337a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
1934803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1935ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1936ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1937fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
19383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
19396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1943fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
19443c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
19456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
19496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1950bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19514a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
19524a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
195307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
195407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
195507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
19564a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
19574a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
19584a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
19594a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
19601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
196287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
19636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1965085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1966fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1967fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1968085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1969085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
19702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1971390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1972390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1973803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1974390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1975fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1976fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
19776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1978bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
19796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
19806217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1981390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1982fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1983fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
19846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
19887a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
1989803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1990ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1991ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1992fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
19933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
19946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
19986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
199987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
20006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
20016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
200287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
20036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
20046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
20056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
20066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
20083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
20092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
20106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
2011fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2012fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
20136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
20146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
20156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
20166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2017fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
20183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
20196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
20216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2022b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
2023b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
202487c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
202587c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
2026b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
2027b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
2028b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
2029b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
2030b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
2031b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
2032b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
2033b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
2034b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->setLocation(Attr.getLoc());
2035b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
2036b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
2037b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
2038b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
203987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
2040cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
20412b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
20426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
20451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
20466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
20471731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
20486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20491731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
20506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
20520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
205387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
20540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
20550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
20560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
205787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
20580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
20590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
2060fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2061883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
20626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
20646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
2066bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
20670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
20680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
20690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
20700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
207117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
207217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
20730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
20740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
20750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
20760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2077bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
20780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
20790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
208090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2081bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
208290cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
208390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
20840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
20850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2086bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
20870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
20880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
20890c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
20900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
20910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
20920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
20930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
20940c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2095bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
20960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2097bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
20980c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
20990c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
21000c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2101bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
21020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
21030c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2104bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2105bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2106bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
21076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2108cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
21096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
21106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
21131731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
21146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21151731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
21167a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2117797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2118bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
21196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
21206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
21216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2122797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
21236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
212587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
2126f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
21276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
21286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
21291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
21306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2131545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
21323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
21336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2135bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2136bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2137bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2138bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
21396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2140545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2141cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
21424ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
21434ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
21444ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
21457a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
21464ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
21474ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
21484ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
21494ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
21504ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2151cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
21526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
21536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2154bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2155cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
215649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
21574ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
21584ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
21594ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
216049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
216149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2162396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
21634ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
21644ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2165396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2166396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2167396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2168cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2169cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2170cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2171cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
2172cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2173cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2174cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
2175cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
21766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2177fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2178d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2179bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2180fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2181bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2182bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2183bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
21841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2185fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2186fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2187fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2188fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
21891731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2190fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
21911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2192fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2193fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2194fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
21950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2196fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2197fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2198210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
21995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Str = Attr.getParameterName()->getName();
2200fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2201fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2202210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2203210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2204fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2205fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2206fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
220773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2208210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2209fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
221073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
221173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
221273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
221373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
221473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
221573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
221673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
221773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
221873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
221973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
222073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
222173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
222273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
222373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
222473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
222573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2226fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2227fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2228fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2229fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2230210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
22310b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2232210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
22330b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
2234fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2235fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2236210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
22370b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2238fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2239fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2240fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2241fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2242162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2243fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2244fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2245fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2246fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2247fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2248fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2249fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2250fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
225173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2252183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
225373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
225473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
22552ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
225673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
225773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
225873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
225973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
226073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
226173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
226273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
226373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
226473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2265390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2266390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2267390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2268390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2269f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2270f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2271fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2272fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2273fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
22743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2275fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2276fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
22773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2278fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2279fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
228073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
228173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
228273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
228373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2284fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
22850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2286fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
22870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2288fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2289fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
229073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
229173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
229273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
229373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2294fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
22950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2296fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
22970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2298fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2299fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2300fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
23010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2302fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
23030b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2304fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
23050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2306fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2307fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2308fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
23090b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2310fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2311aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2312aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2313aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2314aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2315fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2316aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2317aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2318aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2319aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2320fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
232173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
232273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
232373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2324f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2325f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2326f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2327f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2328f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2329f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2330f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2331f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2332f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
233373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2334fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2335fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
233673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
233773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2338fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2339fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2340fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2341162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2342ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2343a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2344ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2345fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2346fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
23470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
23481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2349d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
23501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2351d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2352e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
235387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2354d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2355883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2356d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2357d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2358bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
235987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2360d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2361d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
23621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
23635bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
23641731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
23655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
23661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2367bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
236887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
23695bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2370883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23715bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
23725bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2373bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
237487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
23755bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
23765bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
23771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
23781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
23797255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
23801731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
23817255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
23821731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
23837255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
238487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
23857255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2386883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23877255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
23887255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
23897255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
239087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2391f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
23927255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
23937255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
23941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2395ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2396ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2397831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2398ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2399ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2400ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2401ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
240287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2403ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2404883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2405ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2406ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2407ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
240887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2409ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2410ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2411ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2412ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2413ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
24141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2415ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2416ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2417ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2418ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2419ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2420ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2421ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
242287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2423ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2424883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2425ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2426ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2427ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
242887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2429ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2430ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2431ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2432ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2433ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
24341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2435ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2436ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
24371731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2438ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2439ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
244087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2441ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2442883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2443ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2444ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2445ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
244687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
24472c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2448723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
24492c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
24502c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
24512c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
24522c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
24532c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
24542c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
24552c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
24562c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
24572c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
24582c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
24592c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
24602c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
246187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2462ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2463ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2464ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2465ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2466ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
24671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2468ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2469ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
24701731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2471ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
24721731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2473ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
247487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2475ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2476883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2477ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2478ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2479ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
248087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2481ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2482ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2483ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2484ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2485ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
24861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2487ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2488ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
24891731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2490ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
24911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2492ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
249387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2494ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2495883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2496ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2497ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2498ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
249987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2500ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2501ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2502ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2503ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2504ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
25051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
250626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
25071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
250826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2509bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
251087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2511c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
251226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2513883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
251426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
251526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2516bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25170130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2518cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2519c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2520c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2521bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
252287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
252326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
252426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
25251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
252687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2527711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
252887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2529e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2530711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
253187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
2532711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2533e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
253487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
253587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
253687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2537711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2538711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2539711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
254087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2541e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
254287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2543e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2544e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
254587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2546e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2547f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
254887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
254904633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2550e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
255187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2552e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
255352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
255487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
255552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2556414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
255787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
2558414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
25595cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
256087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2561414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
256287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2563414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2564414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2565414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
25665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2567414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2568414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2569414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2570414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2571414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2572414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
257387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
257487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2575414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2576414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2577414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
257887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PcsAttr(Attr.getLoc(), S.Context, PCS));
2579414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2580e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2581e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2582e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2583e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2584e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2585e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
25861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
258756aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth  assert(!Attr.isInvalid());
258887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2589f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2590f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2591711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2592711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2593711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2594711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2595831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
2596831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2597831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
2598711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2599711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2600711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2601ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
260255d3aaf9a537888734762170823daf750ea9036dEli Friedman
2603414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
2604414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
2605711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2606711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
2607711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2608711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2609711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2610711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2611414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2612414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2613414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
26145cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
2615414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2616414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2617414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2618414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
2619414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2620414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
26215f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2622414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
2623414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
2624414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2625414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
2626414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
2627414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2628414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2629414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
2630414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2631711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
2632711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2633711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2634711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2635711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2636711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
26371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
263887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2639711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2640711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
264187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
2642711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2643711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
264487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
264587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
264687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2647ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2648ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
264955d3aaf9a537888734762170823daf750ea9036dEli Friedman
265087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, numParams));
2651711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2652711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2653711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
2654711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
265587c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
265687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
2657711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2658711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
265987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
266087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
266187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2662711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2663711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2664711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
266587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
266655d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2667ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2668711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
266987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
267055d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
267187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2672711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
267355d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
267455d3aaf9a537888734762170823daf750ea9036dEli Friedman
2675711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (Context.Target.getRegParmMax() == 0) {
267687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
267755d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
267887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2679711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
268055d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
268155d3aaf9a537888734762170823daf750ea9036dEli Friedman
2682711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
2683711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (numParams > Context.Target.getRegParmMax()) {
268487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2685711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
268687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2687711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
268855d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
268955d3aaf9a537888734762170823daf750ea9036dEli Friedman
2690711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2691ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2692ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
26931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
26947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
26957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
26967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
2697bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
2698bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
26997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
27007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
27017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
270287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
27037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2704883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
27057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
27067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
27077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
27087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
27097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
27107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
27117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
27127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
27137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
27147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
27157b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
27167b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
27177b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
27187b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
27197b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
27207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
27217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
27227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
27237b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
27247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
27257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
27267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
27277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
27287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
27297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
273087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
27317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
27327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
27337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
27347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
27357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
27367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
27377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
27380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
2739b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
2740b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
2741b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2742c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
2743c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
2744c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2745c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
2746c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
2747c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2748c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
27491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
275087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
2751c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
275287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
275387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedParameter;
2754c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2755c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2756c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2757c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
275887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
2759c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
2760c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2761c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
2762c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
2763c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2764c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2765c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2766c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
276787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
276887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << cf;
2769c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2770c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2771c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2772c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
277387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getLoc(), S.Context));
2774c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
277587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getLoc(), S.Context));
2776c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2777c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
27781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
27791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
278087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
278187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
278287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedMethod;
2783c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2784c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2785c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
278687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getLoc(), S.Context));
2787c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2788c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
27891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
27901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
2791b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2792c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
2793bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
279487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2795c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
279687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
2797831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
279887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
279987c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
2800f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
280187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
2802c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
28035dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
280487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
280587c44604325578b8de07d768391c1c9432404f5aChandler Carruth        << SourceRange(Attr.getLoc()) << Attr.getName()
2806883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
2807b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
2808b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
2809bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2810c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
2811c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
281287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2813c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
2814c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
2815c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
2816c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
2817c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
2818c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2819c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2820c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2821c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
2822c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
2823c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
2824c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2825c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2826c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2827c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2828c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
282987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
283087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc())
283187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
2832bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
28335dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
2834bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
283587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2836b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
2837b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
2838b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2839c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
284087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getLoc(),
2841c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
2842c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
284331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
284487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(),
2845f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
284631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
284731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
284887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(),
2849f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
285031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
2851b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
285287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(),
2853f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2854b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2855b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
285687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(),
2857f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2858b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2859b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
2860b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
2861b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2862dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
2863dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              const AttributeList &attr) {
2864dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  SourceLocation loc = attr.getLoc();
2865dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
2866dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
2867dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
2868dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!isa<ObjCMethodDecl>(method)) {
2869dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type)
2870dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc, loc) << attr.getName() << 13 /* methods */;
2871dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
2872dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
2873dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
2874dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // Check that the method returns a normal pointer.
2875dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  QualType resultType = method->getResultType();
2876dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (!resultType->isPointerType() || resultType->isObjCRetainableType()) {
2877dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
2878dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << SourceRange(loc)
2879dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
2880dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
2881dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Drop the attribute.
2882dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return;
2883dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
2884dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
2885dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  method->addAttr(
2886dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    ::new (S.Context) ObjCReturnsInnerPointerAttr(loc, S.Context));
2887dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
2888dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
28891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
28901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
289187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2892f85e193739c953358c865005855253af4f68a497John McCall
289387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  SourceLocation L = Attr.getLoc();
289487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
289587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
2896f85e193739c953358c865005855253af4f68a497John McCall}
2897f85e193739c953358c865005855253af4f68a497John McCall
28981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
28991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
290087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
290187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    SourceLocation L = Attr.getLoc();
290287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
290387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
2904f85e193739c953358c865005855253af4f68a497John McCall    return;
2905f85e193739c953358c865005855253af4f68a497John McCall  }
2906f85e193739c953358c865005855253af4f68a497John McCall
290787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
2908f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
2909f85e193739c953358c865005855253af4f68a497John McCall
2910f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
2911f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
291287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
2913f85e193739c953358c865005855253af4f68a497John McCall      << type;
2914f85e193739c953358c865005855253af4f68a497John McCall    return;
2915f85e193739c953358c865005855253af4f68a497John McCall  }
2916f85e193739c953358c865005855253af4f68a497John McCall
2917f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
2918f85e193739c953358c865005855253af4f68a497John McCall
2919f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
2920f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
2921f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
2922f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
2923f85e193739c953358c865005855253af4f68a497John McCall
2924f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
2925f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
2926f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
2927f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
2928f85e193739c953358c865005855253af4f68a497John McCall    break;
2929f85e193739c953358c865005855253af4f68a497John McCall
2930f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
2931f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
2932f85e193739c953358c865005855253af4f68a497John McCall    break;
2933f85e193739c953358c865005855253af4f68a497John McCall
2934f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
2935f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
293687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
2937f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
2938f85e193739c953358c865005855253af4f68a497John McCall    break;
2939f85e193739c953358c865005855253af4f68a497John McCall  }
2940f85e193739c953358c865005855253af4f68a497John McCall
294187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
294287c44604325578b8de07d768391c1c9432404f5aChandler Carruth                 ObjCPreciseLifetimeAttr(Attr.getLoc(), S.Context));
2943f85e193739c953358c865005855253af4f68a497John McCall}
2944f85e193739c953358c865005855253af4f68a497John McCall
2945f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2946f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
294711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
294811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
294911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
295011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
295111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
295211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
295311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
295411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
29551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
295611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
295711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
29581731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
295911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
29601731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
296111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
296211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
29635cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    if (!Str || !Str->isAscii()) {
2964d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2965d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
2966d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2967d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2968d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
29695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef StrRef = Str->getString();
2970d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2971d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
2972d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
2973d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2974d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
2975d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
2976d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2977d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2978d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2979d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
2980d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2981d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2982d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2983d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2984d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
2985d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
29865f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef::iterator I = StrRef.begin();
2987f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
2988f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
2989f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
2990f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
2991d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
2992d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
2993d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2994d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
2995d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
2996d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
2997d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2998d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
2999d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
3000d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
3001d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
300211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
300387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
300411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
3005d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
300611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
3007f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
3008f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
3009b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
30100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
30110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
30120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
30131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
30141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
301560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
30161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
30171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
30181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
301960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
302060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
302160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
302260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
3023e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
30241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
30251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
3026803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
30271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break;
30281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
3029857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
30301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
3031803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
3032207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
3033ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
30346e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
30354211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
30364211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
3037bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
3038bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
3039803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
304060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
304160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
304260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
304360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
304460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
304560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
30461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
30471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
3048bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
30491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
3050b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
30511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
30521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
30531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
3054bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
30551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
30561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
30571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
30581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
30591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
30601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
30613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
30621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
30633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
30641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
30651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
30661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
30671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
30687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
30691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
30707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
30711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
30721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
30731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
30741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
30751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
3076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
3077dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
3078dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
30791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
30801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
30811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
30821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
30831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
30841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
3085b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
3086b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
30871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
3088f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
30891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
3090f85e193739c953358c865005855253af4f68a497John McCall
3091dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case AttributeList::AT_objc_returns_inner_pointer:
3092dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
3093dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
3094b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
3095c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
30961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
3097c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
30981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
3099c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
3100c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
310131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
310231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3103b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3104b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
31051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3106b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
31076f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
31081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
31096f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3110521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
31111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3112521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
31131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
31141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break;
31151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
31161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
3117742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  case AttributeList::AT_arc_weakref_unavailable:
3118742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
3119742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
31201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
31211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
31221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
31231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3124026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
31251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
31261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
31271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3128803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
31291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3130803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
31310db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
31321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
31330db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3134d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
31351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3136d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
31371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break;
31381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
31391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
31401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
31411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
31421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
31431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
31441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
31451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3146bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
314705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
314805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
31497255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
31501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
31517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
315204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
315304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
315404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3155f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
315652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3157414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
31581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
315904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3160f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
31611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3162f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
316311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
31641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
316511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3166fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3167fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  // Thread safety attributes:
3168fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_guarded_var:
3169fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr);
3170fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3171fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_pt_guarded_var:
3172fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleGuardedVarAttr(S, D, Attr, /*pointer = */true);
3173fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3174fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_scoped_lockable:
3175fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr, /*scoped = */true);
3176fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3177fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_no_thread_safety_analysis:
3178fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleNoThreadSafetyAttr(S, D, Attr);
3179fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3180fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski  case AttributeList::AT_lockable:
3181fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    handleLockableAttr(S, D, Attr);
3182fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski    break;
3183fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski
3184803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
318582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
318682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
318782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
31887d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
31897d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3190803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3191803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3192803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3193803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
319460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
319560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
319660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
319760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
31981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
31991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
320060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
320160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
320260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
320360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
320460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
320560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
320660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
320760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
320860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
32091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
321060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
321160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
32121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
321360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
321460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3215803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3216803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3217f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
321860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
321960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
322011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
32211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
322211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
322311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
322411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
322511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
322611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
322760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
322811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3229dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
323011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3231803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3232803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3233803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
3234e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3235e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
32361eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
32377b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3238e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3239e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3240e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3241ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                FD->getInnerLocStart(),
3242e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
3243a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
3244b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
3245b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
3246c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3247b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3248e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3249e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3250ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3251a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
325216573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
325316573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3254b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3255b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3256c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3257b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3258e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3259e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3260e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3261e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3262e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3263e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
32647b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3265c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3266c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3267c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3268c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3269c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
3270cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3271cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3272cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3273c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3274c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3275c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3276c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3277c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3278c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3279c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3280c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3281cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3282e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3283e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3284e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
32850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
32860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
32870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
328860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
328960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3290d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3291d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
329231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor  if (Inheritable) {
329331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    LoadExternalWeakUndeclaredIdentifiers();
329431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor    if (!WeakUndeclaredIdentifiers.empty()) {
329531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
329631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor        if (IdentifierInfo *Id = ND->getIdentifier()) {
329731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
329831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            = WeakUndeclaredIdentifiers.find(Id);
329931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
330031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakInfo W = I->second;
330131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            DeclApplyPragmaWeak(S, ND, W);
330231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor            WeakUndeclaredIdentifiers[Id] = W;
330331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor          }
3304d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3305e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3306e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3307e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3308e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
33090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
33107f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
331160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3312bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
33130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
33140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
33150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
33160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
33170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
33180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
331960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3320bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
33210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
33220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
332360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
33240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
332554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3326f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3327f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3328f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3329f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3330f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3331f85e193739c953358c865005855253af4f68a497John McCall  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl))
3332f85e193739c953358c865005855253af4f68a497John McCall    return false;
3333f85e193739c953358c865005855253af4f68a497John McCall
3334f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3335f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3336f85e193739c953358c865005855253af4f68a497John McCall}
3337f85e193739c953358c865005855253af4f68a497John McCall
3338f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
3339f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3340f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
3341f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
3342f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3343f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
3344f85e193739c953358c865005855253af4f68a497John McCall    return;
3345f85e193739c953358c865005855253af4f68a497John McCall  }
3346f85e193739c953358c865005855253af4f68a497John McCall
3347f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3348f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3349f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
3350f85e193739c953358c865005855253af4f68a497John McCall}
3351f85e193739c953358c865005855253af4f68a497John McCall
3352eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3353eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3354eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3355eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3356eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3357eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3358eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3359eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3360eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3361eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3362eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3363eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3364eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3365eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3366eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3367eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3368eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3369eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3370eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3371eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3372eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
337354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
337454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3375eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3376eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
3377eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
337854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3379eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
3380eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
3381eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
3382eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
338354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3384eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
3385eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
338654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3387eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
3388eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
3389eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
339058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
33912f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
33922f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
3393a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis  if (decl && !decl->isInvalidDecl()) {
3394eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
3395eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
33962f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
33972f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
33982f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
33992f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
34002f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
3401eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3402eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
3403eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
34042f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
34052f514480c448708ec382a684cf5e035d3a827ec8John McCall
3406eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
34072f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
3408eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
34092f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
34102f514480c448708ec382a684cf5e035d3a827ec8John McCall
34112f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
3412eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
34132f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
3414f85e193739c953358c865005855253af4f68a497John McCall
3415f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
3416f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
3417f85e193739c953358c865005855253af4f68a497John McCall        break;
341854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
341954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
342054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
342154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
342258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
3423eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
342429233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
342558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
3426eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
34272f514480c448708ec382a684cf5e035d3a827ec8John McCall}
34282f514480c448708ec382a684cf5e035d3a827ec8John McCall
34292f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
34302f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
34310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
34322f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
34332f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
34342f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
34352f514480c448708ec382a684cf5e035d3a827ec8John McCall}
34362f514480c448708ec382a684cf5e035d3a827ec8John McCall
34379c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
34382f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
34392f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
34402f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
34412f514480c448708ec382a684cf5e035d3a827ec8John McCall
34422f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
3443ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
3444c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
3445ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
3446ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
3447c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
3448c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
3449ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
345054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
345154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
34525f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
34538e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
345489ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
345554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
3456eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3457eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
345854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
345954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
346054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
346154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
346254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
346354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
3464ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
3465c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3466c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
34678e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
3468743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
34698e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
347089ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
34718e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
347289ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
347389ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
34748e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
347554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
3476