SemaDeclAttr.cpp revision a8581b9ca06e6ad504af2e28c0798520364f7f1b
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
52a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d,
53a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  if (const ValueDecl *decl = dyn_cast<ValueDecl>(d))
566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
57a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
59162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  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).
77a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) {
78a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  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.
84a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) {
85a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  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.
91a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) {
92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (isFunctionOrMethod(d))
93620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
99d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  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.
104711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic bool hasDeclarator(const Decl *d) {
105f85e193739c953358c865005855253af4f68a497John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
106f85e193739c953358c865005855253af4f68a497John McCall  return isa<DeclaratorDecl>(d) || isa<BlockDecl>(d) || isa<TypedefNameDecl>(d) ||
107f85e193739c953358c865005855253af4f68a497John McCall         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.
113a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) {
114620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
11572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
116620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
117d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    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).
125a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) {
12689951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
12772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
128d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
129d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
13089951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_size();
1313568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
133a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) {
13489951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
13572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
136d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
137d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13989951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
1403568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1413568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
142a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) {
1435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
1445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
1455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  return cast<ObjCMethodDecl>(d)->getResultType();
1465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
148a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) {
149d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
15072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
152d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
153db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
154d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
1553568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->isVariadic();
1563568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
15907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruthstatic bool isInstanceMethod(const Decl *d) {
16007d7e7a6b10f798459f350b792713db2fb3e9365Chandler 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
197e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
198e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
199e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
200e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
2013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
2023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
2033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
2043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
2069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor                                    const AttributeList &Attr, Sema &S) {
207162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(d);
208545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
209803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
210545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
2149cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2159cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
2169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2179cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
2189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
219f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
220f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
221f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
2224ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
2234ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
2244ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
2254ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
2264ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
2274ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
2289cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
2299cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
2309cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    if (Attr.getNumArgs() != 1) {
2319cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2329cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
2339cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    }
2347a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
2356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2369cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2379cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
2389cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
2399ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
2409cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
241ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
242a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
243bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2449cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
2459cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
2466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
249803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
251545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
255bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
257cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
262803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
263fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
26408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
2656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
266cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
271c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanianstatic void HandleMsStructAttr(Decl *d, const AttributeList &Attr, Sema &S) {
272c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  if (TagDecl *TD = dyn_cast<TagDecl>(d))
273c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getLoc(), S.Context));
274c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
275c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
276c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
277c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
27863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
27996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
28096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
2813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
28296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
28396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
284bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
28563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
28663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
28763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
288cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
28963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
29063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
29163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
2924ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
29363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
29463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
29563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
29663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
29763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (Attr.getNumArgs() > 0) {
29863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
29963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
30063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  }
30163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
30263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
303efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
304efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
305cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
30663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
307efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
30863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
3094ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
31096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
31196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
312857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
313857e918a8a40deb128840308a318bf623d68295fTed Kremenek                                     Sema &S) {
314857e918a8a40deb128840308a318bf623d68295fTed Kremenek
315857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
316a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
317857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
318857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
319857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
320857e918a8a40deb128840308a318bf623d68295fTed Kremenek
321857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
322857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
323857e918a8a40deb128840308a318bf623d68295fTed Kremenek  if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) {
3244ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
325857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
326857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
3273a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian  if (const ValueDecl *VD = dyn_cast<ValueDecl>(d))
3283a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
3293a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
3303a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
3313a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
3323a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
3333a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
3343a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
3353a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
3363a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
3373a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
3383a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
3393a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
340a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
341a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
342a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
3433a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
344b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
345a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian                        S.getScopeForContext(d->getDeclContext()->getParent()));
346a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
347a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
348a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
349a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
350b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
351a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
352a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
353a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
354a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
355a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
356a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
357a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
358a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
359a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
360cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
361cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
362857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
363857e918a8a40deb128840308a318bf623d68295fTed Kremenek
36468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanianstatic void PossibleTransparentUnionPointerType(QualType &T) {
36568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
36668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
36768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
36868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
36968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
37068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
37168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
37268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
37368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
37468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
37568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
37668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
37768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
37868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
379eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
380bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
381bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
382d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
383fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
384883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
385eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
386eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
387bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
38807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
38907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
39007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
39107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
392eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
393eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
394eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
395bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
396eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
397eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
398bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
399bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
400eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
4017a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
402eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
403ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
404ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
405fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
406fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
407eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
408eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
409bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
410eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
412eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
413fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
41430bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
415eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
416eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
417bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
418465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
41907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
42007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
42107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
42207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
42307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
42407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
42507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
42607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
42707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
428eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
429eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
430de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor    QualType T = getFunctionOrMethodArgType(d, x).getNonReferenceType();
43168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    PossibleTransparentUnionPointerType(T);
43268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
433dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
434eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
435c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
436fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
4377fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
438eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
439bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
440eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
441eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
442bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
443bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
444bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
4457fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
44646bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
447de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor      QualType T = getFunctionOrMethodArgType(d, I).getNonReferenceType();
44868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      PossibleTransparentUnionPointerType(T);
449dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
450d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
45146bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
452bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
453ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
45460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
45560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
45660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
45760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
45860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
4597fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
46060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
461eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
4627fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
4637fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
4647fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
465dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
466cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
467cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
468eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
469eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
470dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekstatic void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
471dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
472dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
473dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
475dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
476dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
4772a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
4782a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
482dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
483dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
484dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
485dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
486cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
4872a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
4882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
489cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
490dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
491dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
492dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
493dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4942a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4952a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
496cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
497dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
498dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5012a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
5022a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
503cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
504dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
505dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
506dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
508dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5092a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
5102a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
5112a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
5122a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
513dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
514dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
515dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!isFunction(d) || !hasFunctionProto(d)) {
516883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
517883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
518dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
519dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
520dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
52107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
52207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
52307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
52407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
525dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
526dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::StringRef Module = AL.getParameterName()->getName();
527dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
528dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
530dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
531dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
532dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::SmallVector<unsigned, 10> OwnershipArgs;
533dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
5342a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
5352a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
536dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
5377a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
538dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
539dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
540dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
541dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
542dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
543dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
544dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
545dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
546dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
547dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
548dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
550dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
551dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
552dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
553dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
55407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
55507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
55607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
55707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
55807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
55907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
56007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
56107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
56207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
563dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
564cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
565cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
566dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
567dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      QualType T = getFunctionOrMethodArgType(d, x);
568dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
570dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
571cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
572dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
573dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
574dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
575dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
576dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
577dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
578cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
579dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
580dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
5817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
582dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
583dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
584dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
585dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
586dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
587dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
588dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
589dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
590dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
591dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
592dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5932a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
5942a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
595dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
596dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
597dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
598cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
599cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          i = d->specific_attr_begin<OwnershipAttr>(),
600cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          e = d->specific_attr_end<OwnershipAttr>();
601cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
602cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
603cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
604cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
605cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
606cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
607cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
608dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
609dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
610dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
611dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
612dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
613dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
614dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
615dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
616dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
617dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
618cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
619cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
620cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
621cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
622dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
623cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
624cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
625cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
626dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
627dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
628332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
629332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
630332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
631332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
632332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
633332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
634332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
635332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
636332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
637332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
638332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
639332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
640332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
641332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
642332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
643332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
644332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
64511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
64611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
64711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
64811e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
64911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
65011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
65111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
65211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
65311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
65411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
655332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
656332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
657883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
658332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
659332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
660332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
661332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  NamedDecl *nd = cast<NamedDecl>(d);
662332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
66311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
66411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
66511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
66611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
66711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
66811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
66911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
67011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
67111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
67211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
6737a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  const DeclContext *Ctx = d->getDeclContext()->getRedeclContext();
6747a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
6757a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
676332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
6777a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
67811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
67911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
68011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
68111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
68211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
68311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
68411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
68511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
68611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
68711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
68811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
68911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
69011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
69111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
69211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
69311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
69411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
69511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
69611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
69711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
698332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
699332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
70011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
70111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
70211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
70311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
70411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
70511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
70611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
70711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
7087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
70911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
71011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
71111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
71211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    if (Str == 0 || Str->isWide()) {
71311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
71411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
71511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
71611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
71711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
71811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
719f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher    d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
720f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
72111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
72211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
723cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
72411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
72511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
726803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
728545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
7293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
7306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7337a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
7356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
736bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
738fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
7393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
7406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
742bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
743db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar  if (S.Context.Target.getTriple().isOSDarwin()) {
744f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
745f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
746f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
747f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
7486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
749bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
750f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
751f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
7526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
754dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbarstatic void HandleNakedAttr(Decl *d, const AttributeList &Attr,
755dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar                                   Sema &S) {
756dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
757dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  if (Attr.getNumArgs() != 0) {
758dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
759dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
760dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
761dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
762dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  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
768dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
769dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
770dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
771bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
772af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
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
779c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  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
785cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
786af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
787af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
78876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
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
7952cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
7961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
7972cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
798cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      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
80634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohmanstatic void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
80734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
80834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  if (Attr.getNumArgs() != 0) {
80934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
81034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
81134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  }
81234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
81334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
81434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
81534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
816a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
817a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
818722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  if (isa<VarDecl>(d))
819722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
820722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
821722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
822883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
823a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
824a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
825a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
826a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
827722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  if (isa<VarDecl>(d))
828722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
829722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
830722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
831883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
832a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
833a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
834711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleNoReturnAttr(Decl *d, const AttributeList &attr, Sema &S) {
835711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (hasDeclarator(d)) return;
836711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
837711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
838711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
839711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (!isa<ObjCMethodDecl>(d)) {
840711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
841883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
842711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
843711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
844711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
845711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  d->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
846711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
847711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
848711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
849831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
850711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
851711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
852711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
853711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
854711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
855711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
856b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
857b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
858b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
859b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek                                       Sema &S) {
860b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
861b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
862b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
863b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
864545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
865e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
866b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek    return;
8676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
868b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
86919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
87019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    ValueDecl *VD = dyn_cast<ValueDecl>(d);
8713ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
8723ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
873e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
874e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
875b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
876883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
877b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
87819c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
8796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
880b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
881b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
8826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
88435cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
88535cc9627340b15232139b3c43fcde5973e7fad30John Thompsonstatic void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
88635cc9627340b15232139b3c43fcde5973e7fad30John Thompson                                       Sema &S) {
88735cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
88835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
88935cc9627340b15232139b3c43fcde5973e7fad30John Thompson
890f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
891f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
892f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
893f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
894f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
89535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
89635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
89735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
89835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
89935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
90035cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
90135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
90235cc9627340b15232139b3c43fcde5973e7fad30John Thompson
90335cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
90435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
90535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
90635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
90735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
90835cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
90935cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
91001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<RecordDecl>(d)) {
91135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
912883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
91335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
91435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
91535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
91635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  if (d->getAttr<VecReturnAttr>()) {
91735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
91835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
91935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
92035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
92101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  RecordDecl *record = cast<RecordDecl>(d);
92201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
92301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
92401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
92501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
92601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
92701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
92801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
92901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
93001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
93101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
93201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
93301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
934f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
935f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
93601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
93701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
93801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
93901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
94001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
94101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
94201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
943cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
94435cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
94535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
946bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
947bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
948bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
949883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
950bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
951bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
952bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
953bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
954bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
95573798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
95673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
957831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
9583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
95973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
96073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
961bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
962aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall  if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) &&
96357ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner      !isa<TypeDecl>(d) && !isa<LabelDecl>(d)) {
964fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
965883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
96673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
96773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
968bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
969cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
97073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
97173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
972b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
973b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
974831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
975b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
976b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
977b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
978bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
979b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
980186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
981b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
982b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
983b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
984b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  } else if (!isFunctionOrMethod(d)) {
985b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
986883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
987b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
988b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
990cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
991b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
992b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
9933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
995bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
996bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
9973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
998bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
9993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
10013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
10027a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
10033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1004ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1005ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1006fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
10083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
10093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
10103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
10113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1012bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1013c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
1014fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1015883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
10163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
10173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
10183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1019f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
1020f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
10213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
10223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
10243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1025bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1026bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
10273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1028bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
10293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
10313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
10327a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
10333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1034ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1035ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1036fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
10383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
10393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
10403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
10413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1042bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10436782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
1044fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1045883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
10463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
10473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
10483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1049f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1050f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
10513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
10523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1053803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1054951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1055951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1056bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1057c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1058c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1059951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1060c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
1061951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  llvm::StringRef Str;
1062951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1063951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1064c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1065951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1066951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1067c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1068c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1069951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
10706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1071bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1072951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
10736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1075bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1076951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1077951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1078bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1079bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1080bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1081951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1082c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
1083951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  llvm::StringRef Str;
1084951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1085951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1086c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1087951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1088c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1089c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1090c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1091951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1092c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1093951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
1094bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1095bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
10960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregorstatic void HandleAvailabilityAttr(Decl *d, const AttributeList &Attr,
10970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                   Sema &S) {
10980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
10990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
11000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  llvm::StringRef PlatformName
11020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
11030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
11040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
11050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
11060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
11080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
11110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
11120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1113b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
11140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // Ensure that Introduced < Deprecated < Obsoleted (although not all
11160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
11170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
11180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Deprecated.Version)) {
11190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
11200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
11210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
11220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
11260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Obsoleted.Version)) {
11270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
11280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
11290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
11300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
11340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Deprecated.Version < Obsoleted.Version)) {
11350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
11360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
11370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
11380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  d->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
11420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
11430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
11440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1145b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1146b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                IsUnavailable));
11470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
11480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1149803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
11506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1151545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
11523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1155bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11567a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
11576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
11586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1159bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
1161fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
11623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
11636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1165bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1166c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  llvm::StringRef TypeStr = Str->getString();
1167cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1168bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1169c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1170cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1171c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1172cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1173c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1174cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1175c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1176cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
11776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
117808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
11796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1181bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1182cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
11836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1185d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCallstatic void HandleObjCMethodFamilyAttr(Decl *decl, const AttributeList &attr,
1186d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall                                       Sema &S) {
1187d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1188d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
1189d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    S.Diag(attr.getLoc(), diag::err_attribute_wrong_decl_type)
1190883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1191d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1192d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1193d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1194d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (attr.getNumArgs() != 0 || !attr.getParameterName()) {
1195d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    if (!attr.getParameterName() && attr.getNumArgs() == 1) {
1196d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall      S.Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
1197d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1198d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
1199d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall      S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1200d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
1201d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    attr.setInvalid();
1202d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1203d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1204d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1205d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  llvm::StringRef param = attr.getParameterName()->getName();
1206d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1207d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1208d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1209d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1210d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1211d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1212d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1213d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1214d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1215d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1216d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1217d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1218d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1219d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1220d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1221d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
1222d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    S.Diag(attr.getParameterLoc(), diag::warn_unknown_method_family);
1223d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1224d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1225d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1226f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1227f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1228f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1229f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1230f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1231f85e193739c953358c865005855253af4f68a497John McCall    return;
1232f85e193739c953358c865005855253af4f68a497John McCall  }
1233f85e193739c953358c865005855253af4f68a497John McCall
1234f85e193739c953358c865005855253af4f68a497John McCall  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(attr.getLoc(),
1235f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1236d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1237d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
12380db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
12390db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner                                    Sema &S) {
12400db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
12410db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
12420db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
12430db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1244bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12450db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
12460db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
12470db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
12480db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
12490db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1251cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
12520db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
12530db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
12540db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
1255fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
12562b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1257fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1258fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1259162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1260fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1261fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
12626217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1263fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1264fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1265fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1266fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1267cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1268fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1269fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1270bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
1271f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1272f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
12732b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1274f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1275f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1276f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1277f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1278f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1279f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1280f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1281f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1282cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1283f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1284f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
12859eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1286bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1287fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
12899eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
12909eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1291bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12929eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
12933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12949eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
12959eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1296bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1297cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
129892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
12999eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
13009eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1301fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
13023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
13039eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
13049eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1305bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1306cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
13079eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
13089eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
1309770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1310770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1311770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1312bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1313770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1314bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1315bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1316770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1317770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
13187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1319770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1320ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1321ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1322fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1324770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1325770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1326770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1327bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1328770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1329fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1330fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1331770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1332770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1333770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1334770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1335770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1336770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
13377a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1338770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1339ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1340ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1341fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1343770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1344770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1345770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1346bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1347770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1348770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1349770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1350fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1351fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1352770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1353770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1354770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1355770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1356770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
1357183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1358897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1359bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1360897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1361897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1362897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1363897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1364bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1365897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
13663bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1367770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1368bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
1369770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
1370770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
13713bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1372770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
13732f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
13742f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (isa<BlockDecl>(d)) {
1375bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1376bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
13772f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
13782f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
13792f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1380daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
1381bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
1382f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
13832f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
13843bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
13853bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
13862f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
13872f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1388ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
13892f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1390883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
13912f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
13922f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1393770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1394fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1395883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1396770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1397770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1398f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1399f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1400770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1401770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1402026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
1403026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
1404026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
1405026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1406026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1407026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1408026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1409f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1410026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1411883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1412026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1413026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1414bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1415f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1416f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1417f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1418f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1419f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1420f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1421f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1422f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1423f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1424f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1425f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1426f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1427cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1428026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1429026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1430332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic void HandleWeakAttr(Decl *d, const AttributeList &attr, Sema &S) {
14316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1432831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1433332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
14346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
14366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1437332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
1438332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1439883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedVariableOrFunction;
1440f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1441f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1442f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
1443332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  NamedDecl *nd = cast<NamedDecl>(d);
1444332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1445332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1446332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
1447332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(attr.getLoc(), diag::err_attribute_weak_static);
14486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
14496e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1450bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1451332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  nd->addAttr(::new (S.Context) WeakAttr(attr.getLoc(), S.Context));
14526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
14556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
14566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
14576e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
14586e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
1459bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
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
14826f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
14836f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                    Sema &S) {
14846f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
14856f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  if (Attr.getNumArgs() != 3) {
1486a8581b9ca06e6ad504af2e28c0798520364f7f1bChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
14876f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
14886f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
14896f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
14906f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
14916f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
14927a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
14936f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1494ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1495ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
14966f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
14976f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
14986f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
14996f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
15006f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
15016f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1502cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1503cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
15046f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
15056f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
15066f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
1507026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
150817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
150917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
151017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
151117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
151217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
151317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
151417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
151517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
15167a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1517797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
151817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1519797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
152017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
152117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
15221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1523797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1524bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1525a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1526a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1527a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1528797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1529797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
15301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1531a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1532a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1533a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1534a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1535a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1536a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1537f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1538f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
153917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
154017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
15416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1542803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
15436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1544831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
15453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
15466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1548b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
1549b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  if (NoThrowAttr *Existing = d->getAttr<NoThrowAttr>()) {
1550b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
1551b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      Existing->setLocation(Attr.getLoc());
1552b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
1553b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
1554b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
15556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1557232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1558232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1559831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
15603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1561232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1562232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1563bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1564b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  if (ConstAttr *Existing = d->getAttr<ConstAttr>()) {
1565b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
1566b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor     Existing->setLocation(Attr.getLoc());
1567b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
1568b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1569b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
1570232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1571232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1572232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1573232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1574232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
15753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1576232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1577232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1578bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1579cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1580232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1581232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1582f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1583bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1584f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1585f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1586f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1587bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1588f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1589f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1590f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1591f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1592bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1593f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
1594bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1595f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1596f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1597f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1598f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1599bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1600f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1601c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1602f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1603f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1604f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1605f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
1606f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1607f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1608f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1609f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1610bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1611f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1612f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
1613f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1614f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
1615f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1616f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1617f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1618f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1619f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
1620f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1621f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
1622f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1623f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1624f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1625bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
162689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
162789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
162889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
162989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1630b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
1631b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
1632f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
163389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
163489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
163589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
163689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1637bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1638cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1639223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1640f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1641f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1642bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1643bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1644bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
16455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Attr.getNumArgs() != 1) {
16465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
16475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
16495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
16505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1651883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
16525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
165407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
165507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
165607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
165707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
165807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
16595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
166007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
16615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
16627a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
16635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1664ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1665ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
16665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
16675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
16685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1670bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
16725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
16735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
16745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1676bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1678bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
167907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
168007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
168107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
168207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
168307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
168407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
168507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
168607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
168707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
16885b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
16895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1690bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
16925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
16935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
16945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
16956217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
16965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
16975b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1698bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
16995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
17005b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1701bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
17025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Ty = getFunctionOrMethodResultType(d);
17035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
17045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
17055b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
17066217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
17075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
17085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1709bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
17105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
17115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1712bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1713bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
171407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
171507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
17165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
17175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
17182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
17192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
17202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
17212b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
17222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
17233c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
17242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
17252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
17262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
17272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
17282b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
17292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
17302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
17312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
17322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
17332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
17342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
17352b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
17362b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
17372b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
17382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
17392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
17402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
17412b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
1742cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
1743cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
17442b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
17452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1746bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1747bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
17483c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
17493c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
17502b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
17512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
17522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1753521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
1754521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
1755521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
1756521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian                                   Sema &S) {
1757521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
1758521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1759521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1760521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1761521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1762b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) {
1763b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1764b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1765b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1766b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1767b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  QualType T = dyn_cast<VarDecl>(d)->getType();
1768b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
1769b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
1770b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
1771b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1772b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1773b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1774b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1775b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1776521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
1777521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1778521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1779521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1780521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
17817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
1782b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1783521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
1784521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1785521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1786521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1787521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
1788521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1789521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1790521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
17919f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
1792521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
1793521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1794521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
1795521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1796521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1797521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1798f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
1799f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
1800521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
1801521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1802bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1803bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1804803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
18056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1806545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1807fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
18083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
18096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1812545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
18133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
18146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1817620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1818fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1819883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
18206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
182307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
182407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
182507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
182607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
18276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
18286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
182901eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Format = Attr.getParameterName()->getName();
18306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
18322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
18332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
18342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
18352b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
18362b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
18373c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
18383c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
18393c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
18403c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
18412b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1842fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
184301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
18446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
18487a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
1849803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1850ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1851ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1852fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
18546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1858fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
18593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
18606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
18646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1865bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18664a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
18674a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
186807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
186907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
187007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
18714a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
18724a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
18734a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
18744a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
18751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
18773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
18786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1880085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1881fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1882fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1883085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1884085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
18852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1886390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1887390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1888803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
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        << "an NSString" << IdxExpr->getSourceRange();
18926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1893bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
18946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
18956217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1896390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1897fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1898fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
18996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
19037a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
1904803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1905ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1906ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1907fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
19083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
19096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
19136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
19143568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
19156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
19166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1917803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
19186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
19196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
19206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
19233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
19242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
19256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1926fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1927fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
19286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
19296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
19306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
19316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1932fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
19333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
19346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1937b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
1938b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
1939b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor         i = d->specific_attr_begin<FormatAttr>(),
1940b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor         e = d->specific_attr_end<FormatAttr>();
1941b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
1942b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
1943b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
1944b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
1945b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
1946b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
1947b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
1948b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
1949b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->setLocation(Attr.getLoc());
1950b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
1951b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
1952b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
1953b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
1954cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1955cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
19562b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
19576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
19600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
19616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1962545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
19633c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
19680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
1969162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(d);
19700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
19710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
19720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
19730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = dyn_cast<RecordDecl>(d);
19740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
19750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1976fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1977883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
19786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1982bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
19830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
19840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
19860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
198717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
198817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
19890c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
19900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
19910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1993bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
19940c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
19950c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
199690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
1997bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
199890cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
199990cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
20000c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
20010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2002bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
20030c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
20040c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
20050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
20060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
20070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
20080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
20090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
20100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2011bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
20120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2013bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
20140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
20150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
20160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2017bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
20180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
20190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2020bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2021bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2022bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
20236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2024cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
20256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20270b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
20286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2029545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
20303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
20316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
20337a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2034797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2035bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
20376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
20386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2039797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
20406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2042f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
2043f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
20446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20464ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
20476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2048545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
20493c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
20506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2052bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2053bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2054bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2055bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
20566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2057545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2058cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
20594ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
20604ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
20614ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
20627a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
20634ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
20644ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
20654ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
20664ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
20674ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2068cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
20696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2071bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2072cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
207349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
20744ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
20754ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
20764ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
207749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
207849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2079396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
20804ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
20814ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2082396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2083396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2084396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2085cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2086cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2087cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
2089cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2090cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2091cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
2092cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
20936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2094fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2095bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive
2096bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2097fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2098bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2099bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2100bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
21010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
2102fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2103fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2104fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2105fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
2106fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
21073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2108fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2109fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2110fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2111fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2112fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
21130b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2114fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2115fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2116210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
211701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Str = Attr.getParameterName()->getName();
2118fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2119fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2120210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2121210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2122fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2123fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2124fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
212573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2126210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2127fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
212873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
212973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
213073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
213173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
213273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
213373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
213473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
213573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
213673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
213773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
213873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
213973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
214073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
214173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
214273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
214373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2144fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2145fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2146fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2147fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2148210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
21490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2150210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
21510b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
2152fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2153fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2154210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
21550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2156fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2157fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2158fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2159fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2160162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2161fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2162fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2163fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2164fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2165fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2166fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2167fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2168fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
216973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2170183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
217173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
217273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
21732ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
217473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
217573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
217673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
217773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
217873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
217973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
218073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
218173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
218273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2183390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2184390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2185390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2186390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2187f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2188f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2189fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2190fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2191fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
21923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2193fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2194fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
21953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2196fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2197fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
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.SignedCharTy;
2204fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
22050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2206fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2207fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
220873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
220973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
221073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
221173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2212fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
22130b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2214fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
22150b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2216fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2217fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2218fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
22190b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2220fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
22210b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2222fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
22230b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2224fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2225fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2226fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
22270b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2228fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2229aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2230aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2231aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2232aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2233fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2234aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2235aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2236aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2237aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2238fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
223973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
224073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
224173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2242f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2243f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2244f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2245f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2246f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2247f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2248f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2249f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2250f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
225173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2252fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2253fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
225473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
225573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2256fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2257fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2258fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2259162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2260ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2261a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2262ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2263fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2264fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
22650744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
22661feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2267d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
2268d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
2269d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2270d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2271d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2272e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
22735bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (!isFunctionOrMethod(d)) {
2274d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2275883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2276d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2277d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2278bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2279cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2280d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2281d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
22821feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
22835bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
22845bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
22855bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
22865bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
22875bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2288bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2289c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
22905bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2291883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22925bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
22935bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2294bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2295cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
22965bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
22975bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
22987255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
22997255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner                                           Sema &S) {
23007255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
23017255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (Attr.getNumArgs() != 0) {
23027255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
23037255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
23047255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
23057255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
23067255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (!isa<FunctionDecl>(d)) {
23077255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2308883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23097255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
23107255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
23117255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2312f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2313f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
23147255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
23157255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2316ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2317ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2318ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2319831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2320ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2321ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2322ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2323ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2324ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<VarDecl>(d)) {
2325ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2326883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2327ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2328ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2329ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2330ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2331ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2332ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2333ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2334ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2335ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2336ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2337ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2338ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2339ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2340ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2341ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2342ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2343ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2344ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) {
2345ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2346883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2347ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2348ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2349ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2350ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2351ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2352ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2353ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2354ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2355ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2356ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2357ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2358ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2359ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2360ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2361ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2362ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2363ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2364ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d)) {
2365ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2366883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2367ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2368ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2369ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
23702c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    FunctionDecl *FD = cast<FunctionDecl>(d);
23712c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2372723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
23732c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
23742c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
23752c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
23762c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
23772c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
23782c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
23792c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
23802c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
23812c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
23822c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
23832c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
23842c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2385ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2386ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2387ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2388ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2389ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2390ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2391ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2392ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2393ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2394ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2395ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2396ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2397ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2398ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2399ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d)) {
2400ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2401883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2402ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2403ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2404ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2405ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2406ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2407ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2408ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2409ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2410ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2411ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2412ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2413ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2414ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2415ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2416ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2417ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2418ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2419ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<VarDecl>(d)) {
2420ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2421883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2422ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2423ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2424ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2425ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2426ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2427ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2428ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2429ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2430ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2431cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
243226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
243326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
243426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
243526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
243626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2437bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2438c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
2439c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
244026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2441883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
244226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
244326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2444bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24450130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2446cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2447c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2448c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2449bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2450cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
245126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
245226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
2453711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleCallConvAttr(Decl *d, const AttributeList &attr, Sema &S) {
2454711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (hasDeclarator(d)) return;
2455711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2456711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  // Diagnostic is emitted elsewhere: here we store the (valid) attr
2457e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2458711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
2459711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckCallingConvAttr(attr, CC))
2460711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2461e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2462711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (!isa<ObjCMethodDecl>(d)) {
2463711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2464883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
2465711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2466711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2467711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2468711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2469e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
2470711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) FastCallAttr(attr.getLoc(), S.Context));
2471e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2472e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
2473711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) StdCallAttr(attr.getLoc(), S.Context));
2474e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2475f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
2476711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) ThisCallAttr(attr.getLoc(), S.Context));
247704633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2478e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
2479711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) CDeclAttr(attr.getLoc(), S.Context));
2480e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
248152fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2482711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) PascalAttr(attr.getLoc(), S.Context));
248352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2484414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2485414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2486414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2487414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (Str == 0 || Str->isWide()) {
2488414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      S.Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2489414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2490414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2491414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2492414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2493414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2494414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    llvm::StringRef StrRef = Str->getString();
2495414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2496414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2497414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2498414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2499414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2500414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
2501414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      S.Diag(attr.getLoc(), diag::err_invalid_pcs);
2502414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2503414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2504414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2505414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2506414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    d->addAttr(::new (S.Context) PcsAttr(attr.getLoc(), S.Context, PCS));
2507414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2508e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2509e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2510e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2511e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2512e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2513e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2514f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbournestatic void HandleOpenCLKernelAttr(Decl *d, const AttributeList &Attr, Sema &S){
2515f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  assert(Attr.isInvalid() == false);
2516f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  d->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2517f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2518f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2519711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2520711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2521711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2522711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2523831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
2524831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2525831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
2526711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2527711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2528711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2529ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
253055d3aaf9a537888734762170823daf750ea9036dEli Friedman
2531414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
2532414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
2533711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2534711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
2535711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2536711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2537711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2538711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2539414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2540414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2541414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2542414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (Str == 0 || Str->isWide()) {
2543414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2544414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2545414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2546414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
2547414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2548414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2549414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    llvm::StringRef StrRef = Str->getString();
2550414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
2551414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
2552414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2553414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
2554414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
2555414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2556414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2557414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
2558414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2559711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
2560711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2561711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2562711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2563711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2564711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2565711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleRegparmAttr(Decl *d, const AttributeList &attr, Sema &S) {
2566711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (hasDeclarator(d)) return;
2567711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2568711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
2569711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckRegparmAttr(attr, numParams))
2570711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2571711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2572711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (!isa<ObjCMethodDecl>(d)) {
2573711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2574883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
2575ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2576ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
257755d3aaf9a537888734762170823daf750ea9036dEli Friedman
2578711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  d->addAttr(::new (S.Context) RegparmAttr(attr.getLoc(), S.Context, numParams));
2579711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2580711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2581711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
2582711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
2583711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckRegparmAttr(const AttributeList &attr, unsigned &numParams) {
2584711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2585711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2586711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2587711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.getNumArgs() != 1) {
2588711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2589711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2590711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2591711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2592711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2593711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  Expr *NumParamsExpr = attr.getArg(0);
259455d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2595ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2596711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
2597711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_argument_not_int)
259855d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
2599711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2600711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
260155d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
260255d3aaf9a537888734762170823daf750ea9036dEli Friedman
2603711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (Context.Target.getRegParmMax() == 0) {
2604711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
260555d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
2606711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2607711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
260855d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
260955d3aaf9a537888734762170823daf750ea9036dEli Friedman
2610711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
2611711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (numParams > Context.Target.getRegParmMax()) {
2612711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2613711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
2614711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2615711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
261655d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
261755d3aaf9a537888734762170823daf750ea9036dEli Friedman
2618711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2619ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2620ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
26217b381985353304a7723acb05911ff91634fa1f27Peter Collingbournestatic void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){
26227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
26237b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
26247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
2625bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
2626bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
26277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
26287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (!isFunctionOrMethod(d)) {
26317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2632883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
26337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
26347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
26377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
26387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
26397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
26407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
26417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
26427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
26437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
26447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
26477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
26487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
26497b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
26507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
26517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
26527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
26537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
26547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
26557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
26567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
26597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
26607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
26617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
26627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
26637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
26647b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
26657b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
2667b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
2668b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
2669b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2670c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
2671c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
2672c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2673c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
2674c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
2675c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2676c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2677c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSConsumedAttr(Decl *d, const AttributeList &attr, Sema &S) {
2678c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  ParmVarDecl *param = dyn_cast<ParmVarDecl>(d);
2679c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
2680c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2681883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << SourceRange(attr.getLoc()) << attr.getName() << ExpectedParameter;
2682c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2683c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2684c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2685c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
2686c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (attr.getKind() == AttributeList::AT_ns_consumed) {
2687c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
2688c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2689c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
2690c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
2691c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2692c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2693c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2694c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
2695c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
2696c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << SourceRange(attr.getLoc()) << attr.getName() << cf;
2697c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2698c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2699c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2700c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
2701c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    param->addAttr(::new (S.Context) CFConsumedAttr(attr.getLoc(), S.Context));
2702c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
2703c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    param->addAttr(::new (S.Context) NSConsumedAttr(attr.getLoc(), S.Context));
2704c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2705c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2706c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSConsumesSelfAttr(Decl *d, const AttributeList &attr,
2707c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                     Sema &S) {
2708c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!isa<ObjCMethodDecl>(d)) {
2709c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2710883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << SourceRange(attr.getLoc()) << attr.getName() << ExpectedMethod;
2711c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2712c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2713c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2714c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  d->addAttr(::new (S.Context) NSConsumesSelfAttr(attr.getLoc(), S.Context));
2715c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2716c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2717c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &attr,
2718b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek                                        Sema &S) {
2719b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2720c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
2721bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
27225dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
2723c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
2724831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
2725831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
2726f85e193739c953358c865005855253af4f68a497John McCall  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(d) &&
2727f85e193739c953358c865005855253af4f68a497John McCall           (attr.getKind() == AttributeList::AT_ns_returns_retained))
2728f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
27295dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
2730c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
27315dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
273221531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2733c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall        << SourceRange(attr.getLoc()) << attr.getName()
2734883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
2735b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
2736b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
2737bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2738c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
2739c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
2740c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  switch (attr.getKind()) {
2741c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
2742c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
2743c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
2744c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
2745c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
2746c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2747c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2748c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2749c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
2750c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
2751c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
2752c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2753c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2754c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2755c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2756c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
275721531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
2758c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << SourceRange(attr.getLoc())
2759c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << attr.getName() << isa<ObjCMethodDecl>(d) << cf;
2760bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
27615dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
2762bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2763c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  switch (attr.getKind()) {
2764b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
2765b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
2766b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2767c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
2768c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(attr.getLoc(),
2769c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
2770c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
277131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
2772c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(attr.getLoc(),
2773f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
277431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
277531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
2776c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(attr.getLoc(),
2777f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
277831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
2779b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
2780c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) CFReturnsRetainedAttr(attr.getLoc(),
2781f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2782b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2783b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
2784c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) NSReturnsRetainedAttr(attr.getLoc(),
2785f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2786b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2787b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
2788b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
2789b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2790b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidisstatic void HandleObjCOwnershipAttr(Decl *d, const AttributeList &attr,
2791f85e193739c953358c865005855253af4f68a497John McCall                                   Sema &S) {
2792f85e193739c953358c865005855253af4f68a497John McCall  if (hasDeclarator(d)) return;
2793f85e193739c953358c865005855253af4f68a497John McCall
2794f85e193739c953358c865005855253af4f68a497John McCall  SourceLocation L = attr.getLoc();
2795f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(d->getLocStart(), diag::err_attribute_wrong_decl_type)
2796f85e193739c953358c865005855253af4f68a497John McCall    << SourceRange(L, L) << attr.getName() << 12 /* variable */;
2797f85e193739c953358c865005855253af4f68a497John McCall}
2798f85e193739c953358c865005855253af4f68a497John McCall
2799f85e193739c953358c865005855253af4f68a497John McCallstatic void HandleObjCPreciseLifetimeAttr(Decl *d, const AttributeList &attr,
2800f85e193739c953358c865005855253af4f68a497John McCall                                          Sema &S) {
2801f85e193739c953358c865005855253af4f68a497John McCall  if (!isa<VarDecl>(d) && !isa<FieldDecl>(d)) {
2802f85e193739c953358c865005855253af4f68a497John McCall    SourceLocation L = attr.getLoc();
2803f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(d->getLocStart(), diag::err_attribute_wrong_decl_type)
2804f85e193739c953358c865005855253af4f68a497John McCall      << SourceRange(L, L) << attr.getName() << 12 /* variable */;
2805f85e193739c953358c865005855253af4f68a497John McCall    return;
2806f85e193739c953358c865005855253af4f68a497John McCall  }
2807f85e193739c953358c865005855253af4f68a497John McCall
2808f85e193739c953358c865005855253af4f68a497John McCall  ValueDecl *vd = cast<ValueDecl>(d);
2809f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
2810f85e193739c953358c865005855253af4f68a497John McCall
2811f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
2812f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
2813f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
2814f85e193739c953358c865005855253af4f68a497John McCall      << type;
2815f85e193739c953358c865005855253af4f68a497John McCall    return;
2816f85e193739c953358c865005855253af4f68a497John McCall  }
2817f85e193739c953358c865005855253af4f68a497John McCall
2818f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
2819f85e193739c953358c865005855253af4f68a497John McCall
2820f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
2821f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
2822f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
2823f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
2824f85e193739c953358c865005855253af4f68a497John McCall
2825f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
2826f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
2827f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
2828f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
2829f85e193739c953358c865005855253af4f68a497John McCall    break;
2830f85e193739c953358c865005855253af4f68a497John McCall
2831f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
2832f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
2833f85e193739c953358c865005855253af4f68a497John McCall    break;
2834f85e193739c953358c865005855253af4f68a497John McCall
2835f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
2836f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
2837f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
2838f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
2839f85e193739c953358c865005855253af4f68a497John McCall    break;
2840f85e193739c953358c865005855253af4f68a497John McCall  }
2841f85e193739c953358c865005855253af4f68a497John McCall
2842f85e193739c953358c865005855253af4f68a497John McCall  d->addAttr(::new (S.Context)
2843f85e193739c953358c865005855253af4f68a497John McCall                 ObjCPreciseLifetimeAttr(attr.getLoc(), S.Context));
2844f85e193739c953358c865005855253af4f68a497John McCall}
2845f85e193739c953358c865005855253af4f68a497John McCall
2846f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2847f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
284811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
284911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
285011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
285111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
285211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
285311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
285411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
285511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
285611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichetstatic void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) {
285711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
285811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
285911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    if (Attr.getNumArgs() != 1) {
286011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
286111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
286211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    }
286311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
286411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2865d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (Str == 0 || Str->isWide()) {
2866d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2867d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
2868d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2869d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2870d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2871d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    llvm::StringRef StrRef = Str->getString();
2872d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2873d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
2874d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
2875d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2876d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
2877d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
2878d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2879d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2880d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2881d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
2882d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2883d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2884d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2885d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2886d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
2887d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
2888f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    llvm::StringRef::iterator I = StrRef.begin();
2889f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
2890f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
2891f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
2892f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
2893d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
2894d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
2895d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2896d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
2897d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
2898d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
2899d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2900d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
2901d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
2902d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
2903d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
290411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
290511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    d->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
290611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
2907d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
290811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
2909f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
2910f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
2911b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
29120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
29130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
29140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
291560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessNonInheritableDeclAttr(Scope *scope, Decl *D,
291660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                          const AttributeList &Attr, Sema &S) {
291760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
291860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:      HandleDeviceAttr      (D, Attr, S); break;
291960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:        HandleHostAttr        (D, Attr, S); break;
292060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
292160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
292260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
292360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
292460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
2925e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
292660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessInheritableDeclAttr(Scope *scope, Decl *D,
292760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                       const AttributeList &Attr, Sema &S) {
2928803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
292963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  case AttributeList::AT_IBAction:            HandleIBAction(D, Attr, S); break;
2930857e918a8a40deb128840308a318bf623d68295fTed Kremenek    case AttributeList::AT_IBOutlet:          HandleIBOutlet(D, Attr, S); break;
2931857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
2932857e918a8a40deb128840308a318bf623d68295fTed Kremenek      HandleIBOutletCollection(D, Attr, S); break;
2933803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
2934207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
2935ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
29366e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
29374211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
29384211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
2939bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
2940bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
2941803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
294260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
294360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
294460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
294560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
294660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
294760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
29487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_alias:       HandleAliasAttr       (D, Attr, S); break;
29497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_aligned:     HandleAlignedAttr     (D, Attr, S); break;
2950bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
2951af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
2952b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
2953bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
29547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_annotate:    HandleAnnotateAttr    (D, Attr, S); break;
29550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  case AttributeList::AT_availability:HandleAvailabilityAttr(D, Attr, S); break;
2956bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
29577725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                      HandleDependencyAttr  (D, Attr, S); break;
2958a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  case AttributeList::AT_common:      HandleCommonAttr      (D, Attr, S); break;
2959ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_constant:    HandleConstantAttr    (D, Attr, S); break;
29607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
29617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_deprecated:  HandleDeprecatedAttr  (D, Attr, S); break;
29627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_destructor:  HandleDestructorAttr  (D, Attr, S); break;
29633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
29649cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    HandleExtVectorTypeAttr(scope, D, Attr, S);
29653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
29667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format:      HandleFormatAttr      (D, Attr, S); break;
29677725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format_arg:  HandleFormatArgAttr   (D, Attr, S); break;
2968ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_global:      HandleGlobalAttr      (D, Attr, S); break;
29697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr   (D, Attr, S); break;
29707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
29717b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    HandleLaunchBoundsAttr(D, Attr, S);
29727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
29737725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_mode:        HandleModeAttr        (D, Attr, S); break;
29747725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_malloc:      HandleMallocAttr      (D, Attr, S); break;
297534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  case AttributeList::AT_may_alias:   HandleMayAliasAttr    (D, Attr, S); break;
2976a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  case AttributeList::AT_nocommon:    HandleNoCommonAttr    (D, Attr, S); break;
29777725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nonnull:     HandleNonNullAttr     (D, Attr, S); break;
2978dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
2979dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
2980dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
2981dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      HandleOwnershipAttr     (D, Attr, S); break;
2982dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  case AttributeList::AT_naked:       HandleNakedAttr       (D, Attr, S); break;
29837725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;
29847725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;
2985ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_shared:      HandleSharedAttr      (D, Attr, S); break;
298635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  case AttributeList::AT_vecreturn:   HandleVecReturnAttr   (D, Attr, S); break;
2987b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2988b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
2989b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis    HandleObjCOwnershipAttr(D, Attr, S); break;
2990f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
2991f85e193739c953358c865005855253af4f68a497John McCall    HandleObjCPreciseLifetimeAttr(D, Attr, S); break;
2992f85e193739c953358c865005855253af4f68a497John McCall
2993b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
2994c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
2995c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumed: HandleNSConsumedAttr  (D, Attr, S); break;
2996c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
2997c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    HandleNSConsumesSelfAttr(D, Attr, S); break;
2998c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2999c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
300031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
300131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3002b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3003b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
3004b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    HandleNSReturnsRetainedAttr(D, Attr, S); break;
3005b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
30066f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
30076f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    HandleReqdWorkGroupSize(D, Attr, S); break;
30086f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3009521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
3010521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      HandleInitPriorityAttr(D, Attr, S); break;
3011521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
30127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_packed:      HandlePackedAttr      (D, Attr, S); break;
3013c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  case AttributeList::AT_MsStruct:    HandleMsStructAttr    (D, Attr, S); break;
30147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_section:     HandleSectionAttr     (D, Attr, S); break;
30157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
30167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unused:      HandleUnusedAttr      (D, Attr, S); break;
30177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_used:        HandleUsedAttr        (D, Attr, S); break;
30187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_visibility:  HandleVisibilityAttr  (D, Attr, S); break;
3019026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
3020026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
30217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak:        HandleWeakAttr        (D, Attr, S); break;
302211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  case AttributeList::AT_weakref:     HandleWeakRefAttr     (D, Attr, S); break;
30237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak_import: HandleWeakImportAttr  (D, Attr, S); break;
3024803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
3025803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
3026803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
30270db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
30280db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
30290db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3030d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
3031d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    HandleObjCMethodFamilyAttr(D, Attr, S);
3032d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
30337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nsobject:    HandleObjCNSObject    (D, Attr, S); break;
30347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_blocks:      HandleBlocksAttr      (D, Attr, S); break;
30357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_sentinel:    HandleSentinelAttr    (D, Attr, S); break;
30367725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_const:       HandleConstAttr       (D, Attr, S); break;
30377725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_pure:        HandlePureAttr        (D, Attr, S); break;
30387725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_cleanup:     HandleCleanupAttr     (D, Attr, S); break;
30397725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nodebug:     HandleNoDebugAttr     (D, Attr, S); break;
30407725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noinline:    HandleNoInlineAttr    (D, Attr, S); break;
30417725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_regparm:     HandleRegparmAttr     (D, Attr, S); break;
3042bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
304305f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
304405f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
30457255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
30467255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    HandleNoInstrumentFunctionAttr(D, Attr, S);
30477255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
304804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
304904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
305004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3051f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
305252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3053414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
3054e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    HandleCallConvAttr(D, Attr, S);
305504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3056f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
3057f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    HandleOpenCLKernelAttr(D, Attr, S);
3058f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
305911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
306011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    HandleUuidAttr(D, Attr, S);
306111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3062803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
306382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
306482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
306582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
30667d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
30677d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3068803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3069803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3070803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3071803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
307260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
307360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
307460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
307560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
307660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessDeclAttribute(Scope *scope, Decl *D,
307760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 const AttributeList &Attr, Sema &S,
307860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
307960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
308060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
308160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
308260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
308360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
308460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
308560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
308660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
308760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessNonInheritableDeclAttr(scope, D, Attr, S);
308860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
308960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
309060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessInheritableDeclAttr(scope, D, Attr, S);
309160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
309260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3093803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3094803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3095f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
309660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
309760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
309811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
309960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttribute(S, D, *l, *this, NonInheritable, Inheritable);
310011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
310111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
310211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
310311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
310411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
310560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
310611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3107dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
310811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3109803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3110803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3111803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
3112e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3113e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
31141eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
31157b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3116e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3117e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3118e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3119ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                FD->getInnerLocStart(),
3120e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
3121a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
3122b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
3123b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
3124c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3125b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3126e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3127e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3128ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3129a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
313016573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
313116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3132b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3133b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3134c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3135b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3136e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3137e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3138e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3139e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3140e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3141e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
31427b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3143c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3144c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3145c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3146c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3147c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
3148cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3149cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3150cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3151c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3152c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3153c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3154c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3155c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3156c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3157c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3158c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3159cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3160e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3161e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3162e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
31630744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
31640744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
31650744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
316660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
316760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3168d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3169d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
317060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && !WeakUndeclaredIdentifiers.empty()) {
3171d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall    if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
3172d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall      if (IdentifierInfo *Id = ND->getIdentifier()) {
3173d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
3174d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          = WeakUndeclaredIdentifiers.find(Id);
3175d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
3176d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakInfo W = I->second;
3177d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          DeclApplyPragmaWeak(S, ND, W);
3178d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakUndeclaredIdentifiers[Id] = W;
3179d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3180e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3181e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3182e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3183e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
31840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
31857f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
318660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3187bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
31880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
31890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
31900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
31910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
31920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
31930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
319460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3195bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
31960744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
31970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
319860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
31990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
320054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3201f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3202f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3203f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3204f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3205f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3206f85e193739c953358c865005855253af4f68a497John McCall  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl))
3207f85e193739c953358c865005855253af4f68a497John McCall    return false;
3208f85e193739c953358c865005855253af4f68a497John McCall
3209f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3210f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3211f85e193739c953358c865005855253af4f68a497John McCall}
3212f85e193739c953358c865005855253af4f68a497John McCall
3213f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
3214f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3215f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
3216f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
3217f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3218f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
3219f85e193739c953358c865005855253af4f68a497John McCall    return;
3220f85e193739c953358c865005855253af4f68a497John McCall  }
3221f85e193739c953358c865005855253af4f68a497John McCall
3222f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3223f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3224f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
3225f85e193739c953358c865005855253af4f68a497John McCall}
3226f85e193739c953358c865005855253af4f68a497John McCall
3227eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3228eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3229eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3230eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3231eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3232eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3233eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3234eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3235eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3236eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3237eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3238eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3239eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3240eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3241eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3242eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3243eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3244eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3245eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3246eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3247eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
324854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
324954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3250eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3251eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
3252eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
325354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3254eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
3255eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
3256eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
3257eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
325854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3259eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
3260eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
326154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3262eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
3263eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
3264eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
326558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
32662f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
32672f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
3268a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis  if (decl && !decl->isInvalidDecl()) {
3269eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
3270eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
32712f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
32722f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
32732f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
32742f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
32752f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
3276eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3277eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
3278eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
32792f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
32802f514480c448708ec382a684cf5e035d3a827ec8John McCall
3281eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
32822f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
3283eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
32842f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
32852f514480c448708ec382a684cf5e035d3a827ec8John McCall
32862f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
3287eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
32882f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
3289f85e193739c953358c865005855253af4f68a497John McCall
3290f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
3291f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
3292f85e193739c953358c865005855253af4f68a497John McCall        break;
329354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
329454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
329554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
329654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
329758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
3298eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
329929233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
330058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
3301eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
33022f514480c448708ec382a684cf5e035d3a827ec8John McCall}
33032f514480c448708ec382a684cf5e035d3a827ec8John McCall
33042f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
33052f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
33060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
33072f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
33082f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
33092f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
33102f514480c448708ec382a684cf5e035d3a827ec8John McCall}
33112f514480c448708ec382a684cf5e035d3a827ec8John McCall
33129c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
33132f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
33142f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
33152f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
33162f514480c448708ec382a684cf5e035d3a827ec8John McCall
33172f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
3318ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
3319c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
3320ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
3321ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
3322c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
3323c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
3324ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
332554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
332654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3327ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramervoid Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
33288e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
332989ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
333054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
3331eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3332eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
333354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
333454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
333554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
333654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
333754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
333854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
3339ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
3340c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3341c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
33428e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
3343743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
33448e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
334589ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
33468e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
334789ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
334889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
33498e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
335054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
3351