SemaDeclAttr.cpp revision 1731e202b268bfcd883710e2b10fe44a869bbcb7
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
207e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
208e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
209e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
210e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
2113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
2123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
2133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
2143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
2151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
2161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
21787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
218545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
219803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
220545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
2216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
2249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2259cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
2269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2279cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
2289cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
229f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
230f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
231f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
2324ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
2334ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
2344ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
2354ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
2364ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
2374ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
2389cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
2399cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
2401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
2419cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
2421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2437a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
2446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2459cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2469cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
2479cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
2489ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
2499cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
250ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
251a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
252bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2539cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
2549cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
2556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2601731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
262bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
26387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
264cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
26587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
2666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
269803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
270fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
27108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
2726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
273cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
27987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
280c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getLoc(), S.Context));
281c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
282c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
283c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
284c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
2851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
28696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
2871731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
28896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
289bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
29063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
29187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
29263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
29387c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
29463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
29563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
29663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
2974ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
29863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
29963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
3001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
30163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
3021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
30363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
30463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
30563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
306efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
30787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D)) {
30887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
30963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
310efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
31163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
3124ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
31396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
31496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
3151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
3161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
317857e918a8a40deb128840308a318bf623d68295fTed Kremenek
318857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
319a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
320857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
321857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
322857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
323857e918a8a40deb128840308a318bf623d68295fTed Kremenek
324857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
325857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
32687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!(isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
3274ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
328857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
329857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
33087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
3313a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
3323a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
3333a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
3343a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
3353a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
33687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3373a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
3383a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
3393a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
3403a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
3413a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
3423a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
343a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
344a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
345a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
3463a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
347b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
34887c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
349a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
350a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
351a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
352a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
353b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
354a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
355a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
356a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
357a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
358a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
359a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
360a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
361a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
362a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
36387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
364cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
365857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
366857e918a8a40deb128840308a318bf623d68295fTed Kremenek
367d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
36868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
36968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
37068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
37168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
37268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
37368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
37468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
37568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
37668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
37768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
37868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
37968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
38068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
38168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
3821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
383bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
384bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
38587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
386fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
387883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
388eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
389eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
390bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
39107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
39207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
39387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
39487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
395eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
396eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
397eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
398bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
399eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
400eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
401bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
402bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
403eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
4047a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
405eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
406ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
407ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
408fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
409fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
410eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
411eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
412bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
413eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
414bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
415eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
416fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
41730bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
418eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
419eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
420bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
421465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
42207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
42307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
42407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
42507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
42607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
42707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
42807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
42907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
43007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
431eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
432eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
43387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
434d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
43568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
436dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
437eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
438c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
439fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
4407fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
441eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
442bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
443eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
444eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
445bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
446bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
447bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
4487fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
44987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
45087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
451d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
452dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
453d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
45446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
455bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
456ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
45760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
45860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
45960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
46060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
46160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
4627fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
46360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
464eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
4657fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
4667fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
4677fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
468dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
46987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
470cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
471eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
472eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
4731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
475dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
476dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
477dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
478dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
4802a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
4812a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
482dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
483dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
484dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
485dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
486dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
487dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
488dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
489cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
4902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
4912a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
492cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
493dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
494dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
495dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
496dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4972a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4982a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
499cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
501dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
502dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
503dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5042a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
5052a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
506cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
508dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
509dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
510dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
511dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5122a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
5132a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
5142a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
5152a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
516dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
517dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
51887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
519883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
520883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
521dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
522dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
523dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
52407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
52507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
52687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
52787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
528dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::StringRef Module = AL.getParameterName()->getName();
530dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
531dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
532dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
533dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
534dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
535dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::SmallVector<unsigned, 10> OwnershipArgs;
536dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
5372a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
5382a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
539dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
5407a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
541dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
542dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
543dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
544dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
545dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
546dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
547dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
548dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
550dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
551dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
552dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
553dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
554dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
555dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
556dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
55707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
55807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
55907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
56007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
56107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
56207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
56307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
56407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
56507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
566dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
567cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
568cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
57087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
571dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
572dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
573dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
574cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
575dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
576dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
577dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
578dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
579dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
580dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
581cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
582dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
583dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
5847a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
585dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
586dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
587dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
588dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
589dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
590dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
591dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
592dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
593dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
594dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
595dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5962a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
5972a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
598dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
599dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
600dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
601cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
60287c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
60387c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
604cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
605cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
606cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
607cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
608cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
609cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
610cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
611dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
612dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
613dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
614dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
615dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
616dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
617dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
618dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
619dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
620dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
621cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
622cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
623cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
624cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
625dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
626cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
62787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
628cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
629dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
630dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
631332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
632332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
633332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
634332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
635332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
636332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
637332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
638332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
639332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
640332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
641332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
642332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
643332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
644332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
645332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
646332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
647332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
64811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
64911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
65011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
6511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
65211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
65311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
65411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
65511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
65611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
65711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
65887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
659332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
660883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
661332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
662332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
663332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
66487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
665332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
66611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
66711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
66811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
66911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
67011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
67111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
67211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
67311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
67411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
67511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
67687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
6777a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
6787a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
679332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
6807a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
68111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
68211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
68311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
68411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
68511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
68611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
68711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
68811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
68911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
69011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
69111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
69211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
69311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
69411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
69511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
69611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
69711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
69811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
69911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
70011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
701332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
702332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
70311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
70411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
70511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
70611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
70711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
70811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
70911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
71011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
7117a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
71211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
71311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
71411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
71511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    if (Str == 0 || Str->isWide()) {
71611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
71711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
71811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
71911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
72011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
72111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
72287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
723f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
72411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
72511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
72687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
72711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
72811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
7291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
731545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
7323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
735bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7367a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
7376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
7386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
739bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
741fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
7423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
7436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
745bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
746db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar  if (S.Context.Target.getTriple().isOSDarwin()) {
747f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
748f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
749f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
750f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
7516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
752bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
75387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
754f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
7556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
758dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
7591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
760dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
761dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
76287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
763dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
764883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
765dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
766dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
767dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
76887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
769dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
770dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
7711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
7721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
773dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
774831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
7753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
776af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
777af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
7785bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
77987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
7805bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
781883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
7825bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
7835bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
784bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
78587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
786af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
787af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
7881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
789dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
790831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
79176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
79276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
79376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
7941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
79587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
7972cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
79887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
7992cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
8002cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
801fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
802fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
8032cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
80476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
80576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
8061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
80734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
8081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
80934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
81034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
81187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
81234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
81334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
8141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
815a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
81687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
81787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
818722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
819722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
820883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
821a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
822a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
8231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
824a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
82587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
82687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
827722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
828722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
829883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
830a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
831a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
8321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
83387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
834711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
835711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
836711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
83787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
838711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
839883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
840711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
841711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
842711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
84387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
844711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
845711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
846711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
847831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
848711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
849711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
850711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
851711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
852711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
853711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
854b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
855b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
8561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
8571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
858b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
859b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
860b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
861b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
8621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 0))
8631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth      return;
864b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
86587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
86687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
8673ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
8683ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
869e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
870e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
871b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
872883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
873b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
87419c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
8756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
876b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
87787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
8786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
88035cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
8811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
88235cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
88335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
88435cc9627340b15232139b3c43fcde5973e7fad30John Thompson
885f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
886f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
887f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
888f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
889f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
89035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
89135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
89235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
89335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
89435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
89535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
89635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
89735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
89835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
89935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
90035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
90135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
90235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
90335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
90435cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
90587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
90635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
907883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
90835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
90935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
91035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
91187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
91235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
91335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
91435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
91535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
91687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
91701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
91801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
91901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
92001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
92101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
92201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
92301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
92401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
92501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
92601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
92701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
92801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
929f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
930f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
93101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
93201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
93301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
93401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
93501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
93601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
93701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
93887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
93935cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
94035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
9411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
94287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
943bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
944883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
945bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
946bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
947bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
948bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
949bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
9501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
95173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
952831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
9533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
95473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
95573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
956bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
95787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
95887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
959fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
960883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
96173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
96273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
963bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
96487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
96573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
96673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
9671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
968b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
969831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
970b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
971b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
972b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
973bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
97487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
975186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
976b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
977b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
978b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
97987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
980b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
981883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
982b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
983b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
984bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
98587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
986b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
987b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
9881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
9893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
990bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
991bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
9923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
993bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
9943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
9963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
9977a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
9983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
999ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1000ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1001fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
10033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
10043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
10053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
10063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1007bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
100887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1009fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1010883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
10113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
10123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
10133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
101487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
1015f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
10163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
10173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
10193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1020bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1021bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
10223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1023bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
10243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
10263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
10277a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
10283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1029ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1030ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1031fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
10333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
10343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
10353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
10363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1037bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
103887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1039fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1040883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
10413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
10423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
10433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
104487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1045f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
10463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
10473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1049951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1050951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1051bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1052c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1053c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1054951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1055c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
1056951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  llvm::StringRef Str;
1057951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1058951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1059c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1060951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1061951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1062c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1063c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1064951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
10656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1066bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
106787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
10686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1071951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1072951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1073bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1074bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1075bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1076951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1077c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
1078951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  llvm::StringRef Str;
1079951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1080951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1081c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1082951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1083c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1084c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1085c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1086951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1087c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
108887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
1089bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1090bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1091742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1092742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                            const AttributeList &Attr) {
1093742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  unsigned NumArgs = Attr.getNumArgs();
1094742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  if (NumArgs > 0) {
1095742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1096742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    return;
1097742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  }
1098742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
1099742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1100742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian                                          Attr.getLoc(), S.Context));
1101742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian}
1102742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian
11031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
11041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
11050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
11060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
11070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  llvm::StringRef PlatformName
11090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
11100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
11110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
11120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
11130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
11150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
11180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
11190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1120b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
11210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // Ensure that Introduced < Deprecated < Obsoleted (although not all
11230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
11240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
11250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Deprecated.Version)) {
11260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
11270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
11280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
11290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
11330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Obsoleted.Version)) {
11340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
11350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
11360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
11370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
11410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Deprecated.Version < Obsoleted.Version)) {
11420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
11430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
11440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
11450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
114887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
11490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
11500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
11510a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1152b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1153b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                IsUnavailable));
11540a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
11550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
11576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
11581731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if(!checkAttributeNumArgs(S, Attr, 1))
11596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1160bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11617a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
11626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
11636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1164bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
1166fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
11673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
11686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1171c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  llvm::StringRef TypeStr = Str->getString();
1172cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1174c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1175cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1176c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1177cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1178c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1179cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1180c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1181cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
11826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
118308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
11846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1186bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
118787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
11886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
11911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1192d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1193d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
119487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1195883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1196d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1197d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1198d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
119987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
120087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
120187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1202d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1203d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
120487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1205d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
120687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1207d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1208d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1209d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
121087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  llvm::StringRef param = Attr.getParameterName()->getName();
1211d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1212d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1213d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1214d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1215d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1216d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1217d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1218d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1219d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1220d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1221d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1222d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1223d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1224d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1225d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1226d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
122787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1228d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1229d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1230d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1231f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1232f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1233f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1234f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1235f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1236f85e193739c953358c865005855253af4f68a497John McCall    return;
1237f85e193739c953358c865005855253af4f68a497John McCall  }
1238f85e193739c953358c865005855253af4f68a497John McCall
123987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getLoc(),
1240f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1241d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1242d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
12431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
12441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
12451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
12460db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
1247bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12480db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
12490db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
12500db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
12510db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
12520db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1253bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1254cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
12550db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
12560db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
12571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1258fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
12592b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1260fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1261fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1262162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1263fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1264fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
12656217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1266fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1267fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1268fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1269fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1270cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1271fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1272fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1273bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
12741b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1275f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
12762b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1277f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1278f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1279f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1280f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1281f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1282f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1283f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1284f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1285cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1286f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1287f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
12881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1289bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1290fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
12929eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
12939eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1294bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12959eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
12963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12979eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
12989eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1299bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1300cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
130192e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
13029eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
13039eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1304fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
13053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
13069eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
13079eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1308bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
130987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
13109eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
13119eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
13121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1313770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1314770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1315bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1316770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1317bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1318bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1319770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1320770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
13217a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1322770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1323ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1324ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1325fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1327770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1328770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1329770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1330bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1331770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1332fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1333fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1334770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1335770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1336770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1337770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1338770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1339770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
13407a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1341770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1342ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1343ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1344fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1346770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1347770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1348770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1349bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1350770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1351770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1352770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1353fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1354fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1355770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1356770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1357770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1358770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
135987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1360183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1361897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1362bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1363897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1364897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1365897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1366897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1367bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1368897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
13693bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1370770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1371bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
137287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1373770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
13743bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1375770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
13762f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
137787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (isa<BlockDecl>(D)) {
1378bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1379bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
13802f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
138187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
13822f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1383daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
138487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1385f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
13862f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
13873bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
13883bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
13892f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
13902f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1391ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
13922f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1393883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
13942f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
13952f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1396770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1397fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1398883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1399770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1400770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
140187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1402f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1403770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1404770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
14051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1406026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
14071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1408026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1409026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1410f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1411026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1412883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1413026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1414026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1415bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1416f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1417f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1418f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1419f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1420f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1421f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1422f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1423f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1424f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1425f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1426f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1427f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1428cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1429026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1430026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
14311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
143387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
143487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
14356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
14376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
143887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
143987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
144087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1441f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1442f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1443f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
144487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1445332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1446332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1447332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
144887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
14496e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
14506e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1451bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
145287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  nd->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
14536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
14571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
14586e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
14591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
14606e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
14616e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
14626e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
14630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
14640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
14650a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
14660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
14670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
1468def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1469db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar             (S.Context.Target.getTriple().isOSDarwin() &&
1470def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor              isa<ObjCInterfaceDecl>(D))) {
1471def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
1472def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
1473c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1474883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
14756e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
14766e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
14776e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
14786e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1479cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
14806e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
14816e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
14821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
14831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
14846f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
14851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 3))
14866f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
14876f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
14886f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
14896f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
14907a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
14916f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1492ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1493ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
14946f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
14956f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
14966f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
14976f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
14986f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
14996f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1500cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1501cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
15026f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
15036f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
15046f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
15051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
150617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
15071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
150817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
150917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
151017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
151117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
15127a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1513797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
151417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1515797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
151617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
151717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
15181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1519797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1520bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1521a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1522a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1523a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1524797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1525797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
15261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1527a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1528a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1529a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1530a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1531a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1532a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1533f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1534f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
153517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
153617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
15376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1540831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
15413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
15426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1544b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
154587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
1546b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
1547b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      Existing->setLocation(Attr.getLoc());
1548b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
154987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
1550b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
15516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1554232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1555831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
15563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1557232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1558232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1559bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
156087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
1561b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
1562b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor     Existing->setLocation(Attr.getLoc());
1563b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
156487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1565b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
1566232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1567232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
15681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1569232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
15701731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
1571232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1572bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
157387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1574232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1575232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
15761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1577bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1578f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1579f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1580f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1581bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1582f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1583f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1584f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1585f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1586bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
158787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
1588bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1589f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1590f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1591f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1592f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1593bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1594f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1595c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1596f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1597f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1598f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1599f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
1600f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1601f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1602f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1603f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1604bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1605f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1606f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
1607f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1608f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
1609f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1610f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1611f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1612f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1613f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
1614f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1615f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
1616f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1617f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1618f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1619bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
162089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
162189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
162289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
162389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1624b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
1625b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
1626f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
162789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
162889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
162989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
163089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1631bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
163287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1633223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1634f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1635f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1636bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1637bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
16381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16391731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
16405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16411731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
164287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
16435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1644883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
16455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
164707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
164807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
164907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
165087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
165187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
16525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
165307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
16545b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
16557a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
16565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1657ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1658ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
16595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
16605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
16615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1663bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
16655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
16665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
16675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1669bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1671bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
167207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
167307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
167407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
167507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
167607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
167707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
167807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
167907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
168007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
16815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
168287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
1683bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
16855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
16865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
16875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
16886217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
16895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
16905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1691bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
16925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
16935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1694bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
169587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
16965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
16975b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
16985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
16996217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
17005b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
17015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1702bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
17035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
17045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1705bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1706bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
170787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
170807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
17095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
17105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
17112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
17122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
17132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
17142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
17152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
17163c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
17172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
17182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
17192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
17202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
17212b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
17222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
17232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
17242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
17252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
17262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
17272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
17282b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
17292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
17302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
17312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
17322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
17332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
17342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
1735cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
1736cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
17372b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
17382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1739bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1740bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
17413c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
17423c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
17432b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
17442b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
17452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1746521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
1747521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
17481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
17491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1750521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
1751521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1752521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1753521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1754521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
175587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
1756b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1757b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1758b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1759b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
176087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
1761b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
1762b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
1763b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
1764b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1765b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1766b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1767b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1768b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1769521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
1770521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1771521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1772521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1773521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
17747a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
1775b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1776521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
1777521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1778521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1779521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1780521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
1781521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1782521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1783521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
17849f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
1785521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
1786521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1787521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
1788521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1789521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1790521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
179187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
1792f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
1793521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
1794521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1795bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1796bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
17971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
17986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1799545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1800fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
18013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
18026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1805545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
18063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
18076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
181087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
1811fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1812883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
18136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
181607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
181707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
181887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
181987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
18206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
18216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
182201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Format = Attr.getParameterName()->getName();
18236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
18252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
18262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
18272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
18282b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
18292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
18303c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
18313c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
18323c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
18333c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
18342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1835fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
183601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
18376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
18417a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
1842803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1843ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1844ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1845fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
18476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1851fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
18523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
18536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
18576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1858bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18594a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
18604a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
186107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
186207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
186307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
18644a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
18654a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
18664a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
18674a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
18681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
187087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
18716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1873085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1874fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1875fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1876085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1877085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
18782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1879390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1880390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1881803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1882390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1883fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1884fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
18856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1886bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
18876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
18886217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1889390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1890fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1891fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
18926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
18967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
1897803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1898ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1899ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1900fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
19013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
19026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
19066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
190787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
19086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
19096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
191087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
19116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
19126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
19136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
19163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
19172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
19186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1919fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1920fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
19216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
19226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
19236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
19246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1925fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
19263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
19276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1930b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
1931b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
193287c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
193387c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
1934b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
1935b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
1936b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
1937b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
1938b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
1939b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
1940b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
1941b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
1942b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->setLocation(Attr.getLoc());
1943b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
1944b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
1945b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
1946b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
194787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1948cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
19492b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
19506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
19531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
19546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
19551731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
19566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
19586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
19600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
196187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
19620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
19630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
19640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
196587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
19660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
19670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1968fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1969883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
19706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1974bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
19750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
19760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
19780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
197917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
198017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
19810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
19820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
19830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1985bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
19860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
19870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
198890cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
1989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
199090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
199190cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
19920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1994bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
19950c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
19960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
19970c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
19980c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
19990c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
20000c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
20010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
20020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2003bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
20040c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2005bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
20060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
20070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
20080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2009bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
20100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
20110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2012bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2013bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2014bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
20156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2016cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
20176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
20211731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 1))
20226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20231731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
20247a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2025797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2026bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
20286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
20296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2030797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
20316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
203387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
2034f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
20356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2039545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
20403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
20416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2043bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2044bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2045bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2046bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
20476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2048545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2049cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
20504ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
20514ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
20524ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
20537a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
20544ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
20554ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
20564ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
20574ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
20584ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2059cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
20606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2062bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2063cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
206449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
20654ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
20664ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
20674ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
206849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
206949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2070396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
20714ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
20724ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2073396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2074396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2075396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2076cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2077cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2078cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2079cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
2080cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2081cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2082cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
2083cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
20846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2085fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2086d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2087bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2088fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2089bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2090bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2091bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
20921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2093fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2094fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2095fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2096fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
20971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2098fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
20991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2100fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2101fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2102fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
21030b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2104fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2105fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2106210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
210701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Str = Attr.getParameterName()->getName();
2108fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2109fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2110210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2111210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2112fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2113fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2114fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
211573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2116210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2117fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
211873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
211973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
212073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
212173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
212273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
212373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
212473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
212573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
212673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
212773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
212873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
212973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
213073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
213173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
213273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
213373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2134fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2135fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2136fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2137fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2138210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
21390b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2140210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
21410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
2142fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2143fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2144210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
21450b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2146fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2147fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2148fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2149fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2150162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2151fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2152fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2153fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2154fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2155fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2156fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2157fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2158fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
215973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2160183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
216173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
216273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
21632ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
216473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
216573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
216673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
216773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
216873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
216973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
217073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
217173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
217273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2173390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2174390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2175390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2176390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2177f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2178f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2179fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2180fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2181fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
21823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2183fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2184fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
21853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2186fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2187fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
218873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
218973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
219073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
219173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2192fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
21930b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2194fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
21950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2196fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2197fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
219873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
219973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
220073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
220173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2202fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
22030b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2204fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
22050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2206fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2207fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2208fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
22090b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2210fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
22110b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2212fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
22130b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2214fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2215fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2216fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
22170b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2218fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2219aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2220aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2221aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2222aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2223fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2224aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2225aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2226aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2227aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2228fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
222973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
223073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
223173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2232f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2233f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2234f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2235f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2236f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2237f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2238f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2239f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2240f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
224173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2242fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2243fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
224473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
224573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2246fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2247fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2248fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2249162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2250ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2251a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2252ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2253fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2254fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
22550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
22561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2257d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
22581731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
2259d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2260e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
226187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2262d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2263883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2264d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2265d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2266bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
226787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2268d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2269d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
22701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
22715bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
22721731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
22735bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
22741731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2275bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
227687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
22775bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2278883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22795bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
22805bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2281bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
228287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
22835bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
22845bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
22851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
22861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
22877255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
22881731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
22897255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
22901731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
22917255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
229287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
22937255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2294883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22957255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
22967255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
22977255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
229887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2299f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
23007255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
23017255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
23021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2303ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2304ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2305831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2306ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2307ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2308ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2309ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
231087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2311ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2312883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2313ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2314ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2315ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
231687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2317ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2318ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2319ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2320ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2321ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
23221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2323ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2324ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2325ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2326ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2327ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2328ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2329ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
233087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2331ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2332883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2333ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2334ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2335ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
233687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2337ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2338ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2339ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2340ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2341ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
23421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2343ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2344ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
23451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2346ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2347ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
234887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2349ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2350883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2351ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2352ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2353ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
235487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
23552c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2356723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
23572c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
23582c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
23592c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
23602c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
23612c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
23622c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
23632c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
23642c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
23652c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
23662c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
23672c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
23682c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
236987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2370ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2371ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2372ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2373ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2374ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
23751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2376ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2377ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
23781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2379ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
23801731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2381ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
238287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2383ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2384883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2385ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2386ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2387ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
238887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2389ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2390ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2391ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2392ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2393ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
23941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2395ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2396ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
23971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 0))
2398ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
23991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
2400ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
240187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2402ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2403883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2404ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2405ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2406ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
240787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2408ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2409ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2410ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2411ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2412ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
24131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
241426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
24151731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth  if (!checkAttributeNumArgs(S, Attr, 0))
241626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
2417bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
241887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2419c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
242026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2421883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
242226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
242326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2424bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24250130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2426cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2427c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2428c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2429bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
243087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
243126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
243226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
24331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
243487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2435711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
243687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2437e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2438711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
243987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
2440711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2441e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
244287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
244387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
244487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2445711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2446711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2447711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
244887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2449e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
245087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2451e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2452e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
245387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2454e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2455f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
245687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
245704633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2458e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
245987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2460e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
246152fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
246287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
246352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2464414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
246587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
2466414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2467414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (Str == 0 || Str->isWide()) {
246887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2469414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
247087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2471414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2472414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2473414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2474414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    llvm::StringRef StrRef = Str->getString();
2475414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2476414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2477414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2478414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2479414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2480414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
248187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
248287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2483414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2484414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2485414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
248687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PcsAttr(Attr.getLoc(), S.Context, PCS));
2487414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2488e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2489e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2490e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2491e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2492e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2493e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
24941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
2495f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  assert(Attr.isInvalid() == false);
249687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2497f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2498f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2499711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2500711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2501711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2502711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2503831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
2504831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2505831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
2506711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2507711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2508711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2509ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
251055d3aaf9a537888734762170823daf750ea9036dEli Friedman
2511414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
2512414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
2513711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2514711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
2515711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2516711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2517711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2518711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2519414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2520414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2521414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2522414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (Str == 0 || Str->isWide()) {
2523414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2524414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2525414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2526414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
2527414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2528414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2529414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    llvm::StringRef StrRef = Str->getString();
2530414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
2531414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
2532414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2533414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
2534414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
2535414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2536414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2537414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
2538414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2539711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
2540711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2541711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2542711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2543711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2544711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
25451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
254687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2547711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2548711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
254987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
2550711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2551711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
255287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
255387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
255487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2555ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2556ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
255755d3aaf9a537888734762170823daf750ea9036dEli Friedman
255887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, numParams));
2559711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2560711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2561711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
2562711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
256387c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
256487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
2565711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2566711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
256787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
256887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
256987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2570711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2571711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2572711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
257387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
257455d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2575ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2576711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
257787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
257855d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
257987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2580711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
258155d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
258255d3aaf9a537888734762170823daf750ea9036dEli Friedman
2583711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (Context.Target.getRegParmMax() == 0) {
258487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
258555d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
258687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2587711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
258855d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
258955d3aaf9a537888734762170823daf750ea9036dEli Friedman
2590711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
2591711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (numParams > Context.Target.getRegParmMax()) {
259287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2593711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
259487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2595711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
259655d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
259755d3aaf9a537888734762170823daf750ea9036dEli Friedman
2598711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2599ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2600ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
26011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
26027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
26037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
26047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
2605bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
2606bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
26077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
26087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
261087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
26117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2612883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
26137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
26147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26157b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26167b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
26177b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
26187b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
26197b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
26207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
26217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
26227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
26237b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
26247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
26277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
26287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
26297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
26307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
26317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
26327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
26337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
26347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
26357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
26367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
263887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
26397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
26407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
26417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
26427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
26437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
26447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
26457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
2647b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
2648b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
2649b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2650c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
2651c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
2652c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2653c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
2654c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
2655c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2656c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
26571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
265887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
2659c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
266087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
266187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedParameter;
2662c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2663c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2664c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2665c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
266687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
2667c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
2668c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2669c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
2670c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
2671c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2672c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2673c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2674c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
267587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
267687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << cf;
2677c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2678c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2679c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2680c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
268187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getLoc(), S.Context));
2682c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
268387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getLoc(), S.Context));
2684c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2685c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
26861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
26871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
268887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
268987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
269087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedMethod;
2691c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2692c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2693c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
269487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getLoc(), S.Context));
2695c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2696c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
26971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
26981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
2699b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2700c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
2701bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
270287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2703c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
270487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
2705831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
270687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
270787c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
2708f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
270987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
2710c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
27115dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
271287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
271387c44604325578b8de07d768391c1c9432404f5aChandler Carruth        << SourceRange(Attr.getLoc()) << Attr.getName()
2714883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
2715b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
2716b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
2717bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2718c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
2719c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
272087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2721c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
2722c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
2723c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
2724c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
2725c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
2726c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2727c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2728c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2729c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
2730c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
2731c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
2732c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2733c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2734c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2735c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2736c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
273787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
273887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc())
273987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
2740bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
27415dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
2742bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
274387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2744b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
2745b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
2746b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2747c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
274887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getLoc(),
2749c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
2750c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
275131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
275287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(),
2753f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
275431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
275531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
275687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(),
2757f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
275831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
2759b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
276087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(),
2761f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2762b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2763b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
276487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(),
2765f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2766b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2767b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
2768b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
2769b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
27701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
27711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
277287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2773f85e193739c953358c865005855253af4f68a497John McCall
277487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  SourceLocation L = Attr.getLoc();
277587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
277687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
2777f85e193739c953358c865005855253af4f68a497John McCall}
2778f85e193739c953358c865005855253af4f68a497John McCall
27791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
27801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
278187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
278287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    SourceLocation L = Attr.getLoc();
278387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
278487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
2785f85e193739c953358c865005855253af4f68a497John McCall    return;
2786f85e193739c953358c865005855253af4f68a497John McCall  }
2787f85e193739c953358c865005855253af4f68a497John McCall
278887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
2789f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
2790f85e193739c953358c865005855253af4f68a497John McCall
2791f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
2792f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
279387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
2794f85e193739c953358c865005855253af4f68a497John McCall      << type;
2795f85e193739c953358c865005855253af4f68a497John McCall    return;
2796f85e193739c953358c865005855253af4f68a497John McCall  }
2797f85e193739c953358c865005855253af4f68a497John McCall
2798f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
2799f85e193739c953358c865005855253af4f68a497John McCall
2800f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
2801f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
2802f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
2803f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
2804f85e193739c953358c865005855253af4f68a497John McCall
2805f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
2806f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
2807f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
2808f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
2809f85e193739c953358c865005855253af4f68a497John McCall    break;
2810f85e193739c953358c865005855253af4f68a497John McCall
2811f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
2812f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
2813f85e193739c953358c865005855253af4f68a497John McCall    break;
2814f85e193739c953358c865005855253af4f68a497John McCall
2815f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
2816f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
281787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
2818f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
2819f85e193739c953358c865005855253af4f68a497John McCall    break;
2820f85e193739c953358c865005855253af4f68a497John McCall  }
2821f85e193739c953358c865005855253af4f68a497John McCall
282287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
282387c44604325578b8de07d768391c1c9432404f5aChandler Carruth                 ObjCPreciseLifetimeAttr(Attr.getLoc(), S.Context));
2824f85e193739c953358c865005855253af4f68a497John McCall}
2825f85e193739c953358c865005855253af4f68a497John McCall
2826f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2827f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
282811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
282911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
283011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
283111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
283211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
283311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
283411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
283511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
28361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
283711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
283811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
28391731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth    if (!checkAttributeNumArgs(S, Attr, 1))
284011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
28411731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth
284211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
284311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2844d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (Str == 0 || Str->isWide()) {
2845d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2846d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
2847d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2848d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2849d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2850d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    llvm::StringRef StrRef = Str->getString();
2851d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2852d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
2853d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
2854d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2855d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
2856d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
2857d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2858d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2859d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2860d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
2861d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2862d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2863d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2864d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2865d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
2866d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
2867f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    llvm::StringRef::iterator I = StrRef.begin();
2868f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
2869f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
2870f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
2871f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
2872d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
2873d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
2874d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2875d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
2876d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
2877d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
2878d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2879d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
2880d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
2881d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
2882d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
288311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
288487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
288511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
2886d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
288711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
2888f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
2889f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
2890b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
28910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
28920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
28930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
28941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
28951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
289660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
28971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
28981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
28991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
290060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
290160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
290260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
290360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
2904e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
29051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
29061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
2907803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
29081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break;
29091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
2910857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
29111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
2912803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
2913207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
2914ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
29156e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
29164211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
29174211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
2918bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
2919bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
2920803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
292160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
292260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
292360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
292460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
292560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
292660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
29271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
29281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
2929bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
29301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
2931b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
29321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
29331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
29341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
2935bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
29361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
29371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
29381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
29391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
29401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
29411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
29423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
29431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
29443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
29451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
29461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
29471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
29481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
29497b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
29501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
29517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
29521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
29531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
29541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
29551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
29561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
2957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
2958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
2959dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
29601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
29611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
29621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
29631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
29641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
29651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
2966b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2967b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
29681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
2969f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
29701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
2971f85e193739c953358c865005855253af4f68a497John McCall
2972b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
2973c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
29741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
2975c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
29761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
2977c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2978c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
297931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
298031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
2981b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
2982b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
29831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
2984b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
29856f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
29861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
29876f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
2988521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
29891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
2990521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
29911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
29921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break;
29931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
29941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
2995742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian  case AttributeList::AT_arc_weakref_unavailable:
2996742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    handleArcWeakrefUnavailableAttr (S, D, Attr);
2997742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian    break;
29981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
29991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
30001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
30011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3002026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
30031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
30041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
30051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3006803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
30071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3008803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
30090db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
30101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
30110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3012d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
30131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3014d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
30151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break;
30161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
30171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
30181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
30191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
30201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
30211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
30221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
30231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3024bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
302505f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
302605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
30277255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
30281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
30297255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
303004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
303104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
303204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3033f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
303452fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3035414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
30361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
303704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3038f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
30391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3040f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
304111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
30421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
304311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3044803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
304582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
304682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
304782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
30487d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
30497d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3050803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3051803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3052803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3053803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
305460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
305560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
305660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
305760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
30581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
30591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
306060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
306160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
306260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
306360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
306460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
306560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
306660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
306760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
306860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
30691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
307060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
307160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
30721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
307360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
307460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3075803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3076803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3077f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
307860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
307960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
308011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
30811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
308211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
308311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
308411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
308511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
308611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
308760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
308811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3089dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
309011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3091803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3092803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3093803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
3094e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3095e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
30961eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
30977b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3098e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3099e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3100e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3101ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                FD->getInnerLocStart(),
3102e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
3103a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
3104b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
3105b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
3106c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3107b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3108e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3109e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3110ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3111a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
311216573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
311316573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3114b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3115b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3116c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3117b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3118e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3119e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3120e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3121e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3122e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3123e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
31247b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3125c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3126c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3127c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3128c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3129c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
3130cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3131cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3132cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3133c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3134c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3135c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3136c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3137c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3138c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3139c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3140c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3141cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3142e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3143e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3144e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
31450744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
31460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
31470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
314860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
314960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3150d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3151d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
315260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && !WeakUndeclaredIdentifiers.empty()) {
3153d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall    if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
3154d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall      if (IdentifierInfo *Id = ND->getIdentifier()) {
3155d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
3156d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          = WeakUndeclaredIdentifiers.find(Id);
3157d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
3158d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakInfo W = I->second;
3159d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          DeclApplyPragmaWeak(S, ND, W);
3160d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakUndeclaredIdentifiers[Id] = W;
3161d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3162e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3163e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3164e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3165e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
31660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
31677f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
316860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3169bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
31700744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
31710744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
31720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
31730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
31740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
31750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
317660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
31780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
31790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
318060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
31810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
318254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3183f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3184f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3185f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3186f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3187f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3188f85e193739c953358c865005855253af4f68a497John McCall  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl))
3189f85e193739c953358c865005855253af4f68a497John McCall    return false;
3190f85e193739c953358c865005855253af4f68a497John McCall
3191f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3192f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3193f85e193739c953358c865005855253af4f68a497John McCall}
3194f85e193739c953358c865005855253af4f68a497John McCall
3195f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
3196f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3197f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
3198f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
3199f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3200f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
3201f85e193739c953358c865005855253af4f68a497John McCall    return;
3202f85e193739c953358c865005855253af4f68a497John McCall  }
3203f85e193739c953358c865005855253af4f68a497John McCall
3204f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3205f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3206f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
3207f85e193739c953358c865005855253af4f68a497John McCall}
3208f85e193739c953358c865005855253af4f68a497John McCall
3209eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3210eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3211eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3212eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3213eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3214eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3215eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3216eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3217eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3218eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3219eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3220eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3221eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3222eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3223eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3224eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3225eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3226eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3227eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3228eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3229eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
323054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
323154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3232eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3233eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
3234eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
323554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3236eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
3237eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
3238eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
3239eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
324054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3241eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
3242eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
324354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3244eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
3245eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
3246eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
324758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
32482f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
32492f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
3250a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis  if (decl && !decl->isInvalidDecl()) {
3251eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
3252eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
32532f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
32542f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
32552f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
32562f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
32572f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
3258eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3259eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
3260eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
32612f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
32622f514480c448708ec382a684cf5e035d3a827ec8John McCall
3263eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
32642f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
3265eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
32662f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
32672f514480c448708ec382a684cf5e035d3a827ec8John McCall
32682f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
3269eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
32702f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
3271f85e193739c953358c865005855253af4f68a497John McCall
3272f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
3273f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
3274f85e193739c953358c865005855253af4f68a497John McCall        break;
327554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
327654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
327754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
327854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
327958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
3280eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
328129233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
328258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
3283eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
32842f514480c448708ec382a684cf5e035d3a827ec8John McCall}
32852f514480c448708ec382a684cf5e035d3a827ec8John McCall
32862f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
32872f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
32880a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
32892f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
32902f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
32912f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
32922f514480c448708ec382a684cf5e035d3a827ec8John McCall}
32932f514480c448708ec382a684cf5e035d3a827ec8John McCall
32949c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
32952f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
32962f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
32972f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
32982f514480c448708ec382a684cf5e035d3a827ec8John McCall
32992f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
3300ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
3301c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
3302ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
3303ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
3304c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
3305c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
3306ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
330754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
330854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3309ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramervoid Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
33108e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
331189ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
331254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
3313eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3314eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
331554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
331654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
331754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
331854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
331954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
332054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
3321ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
3322c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3323c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
33248e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
3325743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
33268e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
332789ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
33288e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
332989ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
333089ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
33318e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
333254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
3333