SemaDeclAttr.cpp revision 162e1c1b487352434552147967c3dd296ebee2f7
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"
20fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2119510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
229c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
23797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of
28883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
29883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCallenum {
30883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunction,
31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedUnion,
32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableOrFunction,
33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionOrMethod,
34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameter,
35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameterOrMethod,
36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrBlock,
37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassOrVirtualMethod,
38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrParameter,
39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClass,
40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVirtualMethod,
41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassMember,
42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariable,
43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedMethod,
44883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableFunctionOrLabel
45883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall};
46883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall
47e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
48e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
49e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
51a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d,
52a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  if (const ValueDecl *decl = dyn_cast<ValueDecl>(d))
556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
58162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(d))
596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
62bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
646217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
65755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
666217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
67d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
68183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
713568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
723568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
74d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
75a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
76a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) {
77a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  return getFunctionType(d, false) != NULL;
78a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
79a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
81d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
82d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
83a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) {
84a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  return isFunction(d)|| isa<ObjCMethodDecl>(d);
85d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
863568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
87620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
88620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
90a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) {
91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (isFunctionOrMethod(d))
92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
93620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
98d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  return isa<BlockDecl>(d);
99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
101711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
102711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
103711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic bool hasDeclarator(const Decl *d) {
104162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // In some sense, TypedefNameDecl really *ought* to be a DeclaratorDecl.
105162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  return isa<DeclaratorDecl>(d) || isa<BlockDecl>(d) || isa<TypedefNameDecl>(d);
106711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
107711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
108d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
109d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
110620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
111a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) {
112620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
11372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
114620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
115d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d));
116d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
117d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
1183568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1193568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
121d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
122d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
123a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) {
12489951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
12572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
126d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
127d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
12889951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_size();
1293568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1303568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
131a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) {
13289951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
13372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
134d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
135d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
136bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13789951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
1383568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1393568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
140a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) {
1415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
1425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
1435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  return cast<ObjCMethodDecl>(d)->getResultType();
1445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
146a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) {
147d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
14872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1493568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
150d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
151db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
152d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
1533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->isVariadic();
1543568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1553568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1563568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
15707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruthstatic bool isInstanceMethod(const Decl *d) {
15807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(d))
15907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
16007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
16107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
16207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
164183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
165b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
168506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
169506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
171bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
172506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
179085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1806217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
181085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
182085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
183085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1846217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
187bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
189465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
191085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
192085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
195e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
196e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
197e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
198e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
1993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
2003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
2013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
2023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
2049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor                                    const AttributeList &Attr, Sema &S) {
205162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(d);
206545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
207803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
208545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
2096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
210bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
2129cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2139cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
2149cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2159cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
2169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
217f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
218f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
219f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
220f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>();
2219cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
2229cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
2239cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    if (Attr.getNumArgs() != 1) {
2249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2259cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
2269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    }
2277a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
2286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2299cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2309cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
2319cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
2329ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
2339cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
234ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
235a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
236bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2379cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
2389cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
2396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
242803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
244545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
248bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
250cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
255803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
256fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
25708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
2586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
259cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
26463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
26596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
26696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
2673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
26896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
26996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
270bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
27163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
27263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
27363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
274cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
27563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
27663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
27763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
2784ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
27963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
28063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
28163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
28263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
28363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (Attr.getNumArgs() > 0) {
28463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
28563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
28663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  }
28763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
28863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
289efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
290efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
291cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
29263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
293efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
29463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
2954ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
29696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
29796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
298857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
299857e918a8a40deb128840308a318bf623d68295fTed Kremenek                                     Sema &S) {
300857e918a8a40deb128840308a318bf623d68295fTed Kremenek
301857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
302a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
303857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
304857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
305857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
306857e918a8a40deb128840308a318bf623d68295fTed Kremenek
307857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
308857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
309857e918a8a40deb128840308a318bf623d68295fTed Kremenek  if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) {
3104ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
311857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
312857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
3133a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian  if (const ValueDecl *VD = dyn_cast<ValueDecl>(d))
3143a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
3153a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
3163a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
3173a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
3183a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
3193a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
3203a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
3213a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
3223a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
3233a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
3243a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
3253a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
326a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
327a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
328a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
3293a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
330b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
331a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian                        S.getScopeForContext(d->getDeclContext()->getParent()));
332a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
333a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
334a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
335a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
336b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
337a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
338a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
339a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
340a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
341a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
342a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
343a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
344a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
345a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
346cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
347cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
348857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
349857e918a8a40deb128840308a318bf623d68295fTed Kremenek
350eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
351bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
352bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
353d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
354fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
355883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
356eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
357eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
358bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
35907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
36007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
36107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
36207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
363eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
364eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
365eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
366bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
367eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
368eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
369bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
370bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
371eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
3727a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
373eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
374ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
375ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
376fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
377fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
378eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
379eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
380bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
381eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
382bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
383eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
384fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
38530bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
386eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
387eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
388bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
389465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
39007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
39107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
39207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
39307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
39407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
39507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
39607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
39707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
39807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
399eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
400eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
401de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor    QualType T = getFunctionOrMethodArgType(d, x).getNonReferenceType();
402dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
403eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
404c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
405fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
4067fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
407eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
408bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
409eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
410eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
412bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
413bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
4147fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
41546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
416de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor      QualType T = getFunctionOrMethodArgType(d, I).getNonReferenceType();
417dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
418d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
419ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian      else if (const RecordType *UT = T->getAsUnionType()) {
420ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian        if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
421ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian          RecordDecl *UD = UT->getDecl();
422ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian          for (RecordDecl::field_iterator it = UD->field_begin(),
423ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian               itend = UD->field_end(); it != itend; ++it) {
424ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian            T = it->getType();
425ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian            if (T->isAnyPointerType() || T->isBlockPointerType()) {
426ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian              NonNullArgs.push_back(I);
427ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian              break;
428ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian            }
429ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian          }
430ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian        }
431ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian      }
43246bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
433bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
434ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
43560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
43660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
43760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
43860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
43960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
4407fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
44160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
442eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
4437fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
4447fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
4457fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
446dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
447cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
448cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
449eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
450eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
451dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekstatic void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
452dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
453dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
454dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
455dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
456dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
457dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
4582a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
4592a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
460dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
461dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
462dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
463dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
464dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
465dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
466dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
467cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
4682a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
4692a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
470cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
471dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
472dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
473dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4762a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
477cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
478dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4822a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4832a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
484cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
485dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
486dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
487dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
488dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
489dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4912a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
4922a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
4932a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
494dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
495dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
496dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!isFunction(d) || !hasFunctionProto(d)) {
497883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
498883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
501dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
50207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
50307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
50407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
50507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
506dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::StringRef Module = AL.getParameterName()->getName();
508dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
509dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
510dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
511dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
512dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
513dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::SmallVector<unsigned, 10> OwnershipArgs;
514dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
5152a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
5162a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
517dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
5187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
519dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
520dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
521dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
522dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
523dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
524dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
525dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
526dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
527dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
528dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
530dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
531dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
532dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
533dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
534dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
53507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
53607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
53707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
53807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
53907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
54007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
54107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
54207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
54307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
544dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
545cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
546cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
547dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
548dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      QualType T = getFunctionOrMethodArgType(d, x);
549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
550dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
551dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
552cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
553dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
554dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
555dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
556dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
557dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
558dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
559cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
560dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
561dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
5627a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
563dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
564dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
565dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
566dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
567dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
568dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
570dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
571dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
572dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
573dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5742a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
5752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
576dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
577dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
578dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
579cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
580cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          i = d->specific_attr_begin<OwnershipAttr>(),
581cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          e = d->specific_attr_end<OwnershipAttr>();
582cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
583cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
584cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
585cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
586cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
587cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
588cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
589dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
590dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
591dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
592dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
593dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
594dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
595dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
596dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
597dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
598dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
599cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
600cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
601cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
602cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
603dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
604cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
605cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
606cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
607dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
608dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
609332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
610332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
611332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
612332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
613332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
614332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
615332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
616332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
617332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
618332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
619332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
620332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
621332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
622332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
623332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
624332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
625332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
62611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
62711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
62811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
62911e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
63011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
63111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
63211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
63311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
63411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
63511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
636332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
637332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
638883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
639332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
640332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
641332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
642332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  NamedDecl *nd = cast<NamedDecl>(d);
643332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
64411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
64511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
64611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
64711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
64811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
64911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
65011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
65111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
65211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
65311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
6547a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  const DeclContext *Ctx = d->getDeclContext()->getRedeclContext();
6557a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
6567a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
657332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
6587a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
65911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
66011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
66111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
66211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
66311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
66411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
66511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
66611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
66711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
66811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
66911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
67011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
67111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
67211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
67311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
67411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
67511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
67611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
67711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
67811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
679332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
680332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
68111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
68211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
68311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
68411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
68511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
68611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
68711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
68811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
6897a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
69011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
69111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
69211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
69311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    if (Str == 0 || Str->isWide()) {
69411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
69511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
69611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
69711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
69811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
69911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
700f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher    d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
701f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
70211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
70311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
704cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
70511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
70611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
707803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
7086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
709545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
7103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
7116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
713bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7147a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
717bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
719fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
7203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
7216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
723bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
724f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  if (S.Context.Target.getTriple().getOS() == llvm::Triple::Darwin) {
725f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
726f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
727f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
728f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
730bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
731f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
732f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
735dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbarstatic void HandleNakedAttr(Decl *d, const AttributeList &Attr,
736dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar                                   Sema &S) {
737dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
738dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  if (Attr.getNumArgs() != 0) {
739dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
740dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
741dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
742dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
743dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  if (!isa<FunctionDecl>(d)) {
744dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
745883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
746dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
747dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
748dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
749dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
750dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
751dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
752bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
753af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
754dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
755831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
7563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
757af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
758af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
7595bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
760c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
7615bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
762883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
7635bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
7645bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
765bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
766cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
767af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
768af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
76976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
770dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
771831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
77276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
77376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
77476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
7751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7762cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
7771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
7782cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
779cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
7802cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
7812cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
782fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
783fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
7842cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
78576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
78676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
78734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohmanstatic void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
78834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
78934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  if (Attr.getNumArgs() != 0) {
79034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
79134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
79234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  }
79334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
79434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
79534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
79634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
797a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
798a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
799722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  if (isa<VarDecl>(d))
800722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
801722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
802722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
803883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
804a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
805a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
806a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
807a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
808722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  if (isa<VarDecl>(d))
809722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
810722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
811722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
812883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
813a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
814a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
815711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleNoReturnAttr(Decl *d, const AttributeList &attr, Sema &S) {
816711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (hasDeclarator(d)) return;
817711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
818711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
819711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
820711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (!isa<ObjCMethodDecl>(d)) {
821711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
822883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
823711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
824711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
825711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
826711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  d->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
827711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
828711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
829711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
830831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
831711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
832711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
833711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
834711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
835711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
836711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
837b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
838b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
839b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
840b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek                                       Sema &S) {
841b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
842b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
843b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
844b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
845545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
846e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
847b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek    return;
8486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
849b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
85019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
85119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    ValueDecl *VD = dyn_cast<ValueDecl>(d);
8523ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
8533ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
854e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
855e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
856b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
857883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
858b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
85919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
8606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
861b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
862b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
8636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
86535cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
86635cc9627340b15232139b3c43fcde5973e7fad30John Thompsonstatic void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
86735cc9627340b15232139b3c43fcde5973e7fad30John Thompson                                       Sema &S) {
86835cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
86935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
87035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
871f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
872f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
873f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
874f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
875f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
87635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
87735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
87835cc9627340b15232139b3c43fcde5973e7fad30John Thompson
87935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
88035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
88135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
88235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
88335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
88435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
88535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
88635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
88735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
88835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
88935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
89035cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
89101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<RecordDecl>(d)) {
89235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
893883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
89435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
89535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
89635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
89735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  if (d->getAttr<VecReturnAttr>()) {
89835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
89935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
90035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
90135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
90201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  RecordDecl *record = cast<RecordDecl>(d);
90301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
90401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
90501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
90601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
90701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
90801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
90901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
91001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
91101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
91201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
91301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
91401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
915f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
916f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
91701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
91801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
91901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
92001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
92101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
92201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
92301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
924cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
92535cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
92635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
927bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
928bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
929bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
930883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
931bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
932bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
933bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
934bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
935bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
93673798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
93773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
938831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
9393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
94073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
94173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
942bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
943aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall  if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) &&
94457ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner      !isa<TypeDecl>(d) && !isa<LabelDecl>(d)) {
945fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
946883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
94773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
94873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
949bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
950cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
95173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
95273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
953b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
954b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
955831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
956b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
957b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
958b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
959bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
960b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
961186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
962b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
963b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
964b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
965b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  } else if (!isFunctionOrMethod(d)) {
966b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
967883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
968b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
969b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
970bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
971cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
972b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
973b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
9743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
976bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
977bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
9783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
979bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
9803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
9823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
9837a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
9843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
985ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
986ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
987fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
9883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
9893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
9903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
9913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
9923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
993bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
994c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
995fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
996883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
9973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
9983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
9993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1000f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
1001f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
10023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
10033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
10053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1006bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1007bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
10083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1009bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
10103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
10123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
10137a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
10143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1015ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1016ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1017fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
10193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
10203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
10213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
10223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1023bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10246782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
1025fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1026883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
10273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
10283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
10293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1030f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1031f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
10323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
10333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1034803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1035951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1036951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1037bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1038c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1039c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1040951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1041c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
1042951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  llvm::StringRef Str;
1043951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1044951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1045c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1046951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1047951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1048c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1049c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1050951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
10516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1052bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1053951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
10546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1056bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1057951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1058951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1059bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1060bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1061bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1062951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1063c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
1064951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  llvm::StringRef Str;
1065951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1066951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1067c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1068951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1069c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1070c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1071c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1072951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1073c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1074951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
1075bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1076bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
10770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregorstatic void HandleAvailabilityAttr(Decl *d, const AttributeList &Attr,
10780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                   Sema &S) {
10790a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
10800a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
10810a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
10820a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  llvm::StringRef PlatformName
10830a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
10840a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
10850a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
10860a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
10870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
10880a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
10890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
10900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
10910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
10920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
10930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1094b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
10950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
10960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // Ensure that Introduced < Deprecated < Obsoleted (although not all
10970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
10980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
10990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Deprecated.Version)) {
11000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
11010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
11020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
11030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
11070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Obsoleted.Version)) {
11080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
11090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
11100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
11110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
11150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Deprecated.Version < Obsoleted.Version)) {
11160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
11170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
11180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
11190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  d->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
11230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
11240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
11250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1126b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1127b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                IsUnavailable));
11280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
11290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1130803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
11316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1132545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
11333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1136bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11377a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
11386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
11396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
1142fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
11433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
11446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1146bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1147c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  llvm::StringRef TypeStr = Str->getString();
1148cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1149bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1150c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1151cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1152c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1153cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1154c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1155cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1156c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1157cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
11586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
115908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
11606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1162bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1163cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
11646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1166d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCallstatic void HandleObjCMethodFamilyAttr(Decl *decl, const AttributeList &attr,
1167d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall                                       Sema &S) {
1168d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1169d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
1170d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    S.Diag(attr.getLoc(), diag::err_attribute_wrong_decl_type)
1171883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1172d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1173d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1174d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1175d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (attr.getNumArgs() != 0 || !attr.getParameterName()) {
1176d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    if (!attr.getParameterName() && attr.getNumArgs() == 1) {
1177d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall      S.Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
1178d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1179d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
1180d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall      S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1181d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
1182d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    attr.setInvalid();
1183d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1184d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1185d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1186d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  llvm::StringRef param = attr.getParameterName()->getName();
1187d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1188d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1189d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1190d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1191d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1192d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1193d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1194d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1195d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1196d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1197d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1198d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1199d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1200d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1201d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1202d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
1203d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    S.Diag(attr.getParameterLoc(), diag::warn_unknown_method_family);
1204d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1205d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1206d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1207d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  decl->addAttr(new (S.Context) ObjCMethodFamilyAttr(attr.getLoc(),
1208d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall                                                     S.Context, family));
1209d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1210d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
12110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
12120db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner                                    Sema &S) {
12130db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
12140db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
12150db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
12160db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1217bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12180db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
12190db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
12200db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
12210db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
12220db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1223bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1224cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
12250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
12260db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
12270db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
1228fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
12292b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1230fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1231fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1232162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1233fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1234fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
12356217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1236fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1237fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1238fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1239fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1240cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1241fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1242fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1243bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
1244f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1245f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
12462b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1247f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1248f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1249f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1250f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1251f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1252f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1253f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1254f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1255cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1256f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1257f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
12589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1259bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1260fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
12629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
12639eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1264bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12659eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
12663c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12679eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
12689eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1269bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1270cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
127192e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
12729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
12739eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1274fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
12753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
12769eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
12779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1278bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1279cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
12809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
12819eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
1282770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1283770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1284770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1285bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1286770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1287bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1288bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1289770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1290770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
12917a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1292770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1293ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1294ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1295fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
12963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1297770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1298770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1299770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1300bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1301770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1302fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1303fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1304770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1305770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1306770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1307770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1308770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1309770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
13107a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1311770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1312ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1313ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1314fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1316770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1317770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1318770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1319bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1320770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1321770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1322770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1323fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1324fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1325770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1326770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1327770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1328770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1329770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
1330183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1331897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1332bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1333897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1334897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1335897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1336897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1337bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1338897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
13393bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1340770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1341bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
1342770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
1343770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
13443bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1345770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
13462f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
13472f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (isa<BlockDecl>(d)) {
1348bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1349bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
13502f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
13512f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
13522f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1353daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
1354bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
1355f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
13562f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
13573bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
13583bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
13592f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
13602f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1361ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
13622f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1363883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
13642f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
13652f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1366770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1367fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1368883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1369770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1370770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1371f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1372f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1373770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1374770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1375026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
1376026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
1377026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
1378026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1379026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1380026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1381026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1382f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1383026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1384883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1385026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1386026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1387bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1388f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1389f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1390f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1391f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1392f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1393f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1394f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1395f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1396f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1397f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1398f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1399f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1400cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1401026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1402026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1403332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic void HandleWeakAttr(Decl *d, const AttributeList &attr, Sema &S) {
14046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1405831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
1406332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
14076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
14096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1410332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
1411332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1412883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedVariableOrFunction;
1413f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1414f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1415f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
1416332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  NamedDecl *nd = cast<NamedDecl>(d);
1417332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1418332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1419332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
1420332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(attr.getLoc(), diag::err_attribute_weak_static);
14216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
14226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1423bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1424332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  nd->addAttr(::new (S.Context) WeakAttr(attr.getLoc(), S.Context));
14256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
14286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
14296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
14306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
14316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
1432bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14336e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
14346e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
14356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
14360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
14370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
14380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
14390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
14400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
1441def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1442def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor             (S.Context.Target.getTriple().getOS() == llvm::Triple::Darwin &&
1443def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor              isa<ObjCInterfaceDecl>(D))) {
1444def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
1445def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
1446c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1447883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
14486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
14496e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
14506e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
14516e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1452cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
14536e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
14546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
14556f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
14566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                    Sema &S) {
14576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
14586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  if (Attr.getNumArgs() != 3) {
14592b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
14606f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
14616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
14626f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
14636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
14646f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
14657a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
14666f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1467ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1468ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
14696f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
14706f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
14716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
14726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
14736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
14746f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1475cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1476cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
14776f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
14786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
14796f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
1480026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
148117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
148217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
148317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
148417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
148517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
148617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
148717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
148817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
14897a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1490797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
149117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1492797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
149317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
149417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
14951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1496797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1497bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1498a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1499a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1500a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1501797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1502797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
15031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1504a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1505a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1506a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1507a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1508a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1509a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1510f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1511f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
151217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
151317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
15146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1515803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
15166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1517831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
15183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
15196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1521bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1522cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
15236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1525232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1526232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1527831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
15283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1529232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1530232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1531bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1532cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1533232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1534232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1535232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1536232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1537232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
15383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1539232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1540232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1541bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1542cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1543232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1544232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1545f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1546bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1547f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1548f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1549f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1550bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1551f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1552f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1553f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1554f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1555bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1556f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
1557bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1558f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1559f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1560f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1561f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1562bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1563f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1564c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1565f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1566f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1567f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1568f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
1569f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1570f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1571f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1572f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1573bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1574f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1575f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
1576f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1577f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
1578f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1579f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1580f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1581f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1582f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
1583f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1584f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
1585f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1586f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1587f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1588bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
158989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
159089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
159189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
159289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1593b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
1594b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
1595f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
159689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
159789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
159889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
159989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1600bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1601cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1602223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1603f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1604f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1605bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1606bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1607bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
16085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Attr.getNumArgs() != 1) {
16095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
16105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
16125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
16135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1614883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
16155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
161707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
161807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
161907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
162007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
162107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
16225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
162307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
16245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
16257a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
16265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1627ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1628ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
16295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
16305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
16315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1633bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
16355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
16365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
16375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1639bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1641bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
164207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
164307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
164407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
164507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
164607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
164707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
164807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
164907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
165007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
16515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
16525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1653bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16545b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
16555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
16565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
16575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
16586217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
16595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
16605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1661bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
16625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
16635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1664bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
16655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Ty = getFunctionOrMethodResultType(d);
16665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
16675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
16685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
16696217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
16705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
16715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1672bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
16735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
16745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1675bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1676bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
167707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
167807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
16795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
16805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
16812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
16822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
16832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
16842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
16852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
16863c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
16872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
16882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
16892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
16902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
16912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
16922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
16932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
16942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
16952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
16962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
16972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
16982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
16992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
17002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
17012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
17022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
17032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
17042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
1705cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
1706cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
17072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
17082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1709bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1710bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
17113c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
17123c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
17132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
17142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
17152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1716521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
1717521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
1718521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
1719521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian                                   Sema &S) {
1720521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
1721521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1722521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1723521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1724521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1725b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) {
1726b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1727b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1728b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1729b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1730b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  QualType T = dyn_cast<VarDecl>(d)->getType();
1731b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
1732b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
1733b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
1734b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1735b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1736b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1737b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1738b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1739521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
1740521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1741521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1742521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1743521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
17447a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
1745b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1746521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
1747521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1748521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1749521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1750521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
1751521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1752521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1753521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
17549f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
1755521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
1756521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1757521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
1758521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1759521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1760521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1761f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
1762f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
1763521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
1764521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1765bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1766bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1767803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
17686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1769545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1770fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
17713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
17726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1775545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
17763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
17776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1780620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1781fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1782883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
17836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
178607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
178707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
178807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
178907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
17906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
17916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
179201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Format = Attr.getParameterName()->getName();
17936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
17952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
17962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
17972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
17982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
17992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
18003c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
18013c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
18023c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
18033c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
18042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1805fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
180601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
18076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
18117a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
1812803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1813ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1814ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1815fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
18176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1821fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
18223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
18236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
18276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1828bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18294a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
18304a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
183107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
183207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
183307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
18344a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
18354a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
18364a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
18374a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
18381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
18403568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
18416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18422b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1843085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1844fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1845fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1846085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1847085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
18482b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1849390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1850390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1851803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1852390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1853fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1854fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
18556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1856bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
18576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
18586217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1859390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1860fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1861fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
18626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
18667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
1867803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1868ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1869ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1870fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
18726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
18766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
18773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
18786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
18796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1880803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
18816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
18826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
18836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
18863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
18872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
18886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1889fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1890fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
18916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
18926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
18936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
18946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1895fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
18963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
18976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1900cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1901cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
19022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
19036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
19060b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
19076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1908545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
19093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
19140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
1915162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(d);
19160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
19170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
19180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
19190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = dyn_cast<RecordDecl>(d);
19200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
19210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1922fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1923883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
19246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1928bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
19290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
19300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
19320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
193317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
193417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
19350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
19360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
19370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1939bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
19400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
19410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
194290cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
1943bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
194490cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
194590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
19460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1948bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
19490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
19500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
19510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
19520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
19530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
19540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
19550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
19560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1957bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
19580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
1959bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
19600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
19610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
19620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1963bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
19640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
19650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
1966bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1967bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1968bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
19696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1970cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
19716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
19746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1975545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
19763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
19776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19797a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1980797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1981bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
19836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
19846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
1985797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
19866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1988f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
1989f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
19906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19924ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
19936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1994545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
19953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
19966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1998bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1999bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2000bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2001bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
20026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2003545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2004cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
20054ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
20064ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
20074ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
20087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
20094ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
20104ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
20114ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
20124ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
20134ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2014cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
20156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2017bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2018cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
201949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
20204ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
20214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
20224ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
202349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
202449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2025396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
20264ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
20274ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2028396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2029396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2030396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2031cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2032cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2033cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2034cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
2035cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2036cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2037cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
2038cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
20396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2040fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2041bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive
2042bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2043fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2044bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2045bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2046bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
20470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
2048fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2049fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2050fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2051fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
2052fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
20533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2054fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2055fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2056fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2057fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2058fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
20590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2060fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2061fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2062210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
206301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Str = Attr.getParameterName()->getName();
2064fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2065fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2066210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2067210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2068fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2069fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2070fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
207173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2072210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2073fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
207473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
207573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
207673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
207773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
207873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
207973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
208073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
208173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
208273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
208373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
208473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
208573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
208673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
208773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
208873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
208973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2090fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2091fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2092fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2093fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2094210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
20950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2096210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
20970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
2098fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2099fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2100210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
21010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2102fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2103fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2104fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2105fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2106162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2107fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2108fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2109fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2110fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2111fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2112fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2113fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2114fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
211573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2116183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
211773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
211873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
21192ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
212073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
212173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
212273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
212373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
212473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
212573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
212673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
212773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
212873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2129390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2130390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2131390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2132390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2133f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2134f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2135fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2136fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2137fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
21383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2139fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2140fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
21413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2142fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2143fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
214473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
214573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
214673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
214773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2148fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
21490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2150fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
21510b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2152fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2153fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
215473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
215573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
215673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
215773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2158fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
21590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2160fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
21610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2162fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2163fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2164fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
21650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2166fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
21670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2168fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
21690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2170fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2171fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2172fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
21730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2174fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2175aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2176aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2177aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2178aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2179fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2180aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2181aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2182aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2183aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2184fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
218573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
218673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
218773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2188f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2189f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2190f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2191f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2192f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2193f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2194f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2195f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2196f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
219773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2198fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2199fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
220073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
220173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2202fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2203fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2204fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2205162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2206ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2207a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2208ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2209fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2210fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
22110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
22121feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2213d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
2214d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
2215d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2216d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2217d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2218e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
22195bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (!isFunctionOrMethod(d)) {
2220d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2221883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2222d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2223d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2224bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2225cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2226d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2227d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
22281feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
22295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
22305bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
22315bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
22325bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
22335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2235c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
22365bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2237883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22385bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
22395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2240bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2241cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
22425bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
22435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
22447255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
22457255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner                                           Sema &S) {
22467255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
22477255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (Attr.getNumArgs() != 0) {
22487255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
22497255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
22507255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
22517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
22527255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (!isa<FunctionDecl>(d)) {
22537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2254883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
22567255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
22577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2258f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2259f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
22607255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
22617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2262ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2263ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2264ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2265831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2266ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2267ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2268ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2269ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2270ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<VarDecl>(d)) {
2271ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2272883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2273ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2274ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2275ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2276ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2277ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2278ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2279ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2280ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2281ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2282ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2283ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2284ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2285ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2286ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2287ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2288ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2289ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2290ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) {
2291ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2292883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2293ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2294ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2295ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2296ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2297ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2298ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2299ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2300ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2301ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2302ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2303ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2304ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2305ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2306ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2307ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2308ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2309ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2310ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d)) {
2311ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2312883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2313ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2314ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2315ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
23162c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    FunctionDecl *FD = cast<FunctionDecl>(d);
23172c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2318723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
23192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
23202c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
23212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
23222c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
23232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
23242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
23252c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
23262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
23272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
23282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
23292c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
23302c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2331ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2332ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2333ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2334ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2335ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2336ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2337ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2338ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2339ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2340ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2341ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2342ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2343ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2344ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2345ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d)) {
2346ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2347883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2348ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2349ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2350ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2351ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2352ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2353ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2354ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2355ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2356ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2357ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2358ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2359ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2360ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2361ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2362ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2363ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2364ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2365ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<VarDecl>(d)) {
2366ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2367883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2368ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2369ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2370ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2371ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2372ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2373ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2374ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2375ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2376ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2377cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
237826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
237926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
238026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
238126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
238226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2383bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2384c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
2385c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
238626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2387883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
238826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
238926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2390bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
23910130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2392cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2393c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2394c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2395bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2396cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
239726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
239826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
2399711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleCallConvAttr(Decl *d, const AttributeList &attr, Sema &S) {
2400711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (hasDeclarator(d)) return;
2401711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2402711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  // Diagnostic is emitted elsewhere: here we store the (valid) attr
2403e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2404711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
2405711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckCallingConvAttr(attr, CC))
2406711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2407e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2408711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (!isa<ObjCMethodDecl>(d)) {
2409711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2410883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
2411711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2412711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2413711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2414711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2415e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
2416711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) FastCallAttr(attr.getLoc(), S.Context));
2417e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2418e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
2419711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) StdCallAttr(attr.getLoc(), S.Context));
2420e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2421f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
2422711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) ThisCallAttr(attr.getLoc(), S.Context));
242304633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2424e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
2425711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) CDeclAttr(attr.getLoc(), S.Context));
2426e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
242752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2428711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) PascalAttr(attr.getLoc(), S.Context));
242952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2430414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2431414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2432414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2433414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (Str == 0 || Str->isWide()) {
2434414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      S.Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2435414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2436414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2437414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2438414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2439414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2440414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    llvm::StringRef StrRef = Str->getString();
2441414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2442414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2443414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2444414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2445414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2446414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
2447414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      S.Diag(attr.getLoc(), diag::err_invalid_pcs);
2448414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2449414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2450414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2451414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2452414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    d->addAttr(::new (S.Context) PcsAttr(attr.getLoc(), S.Context, PCS));
2453414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2454e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2455e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2456e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2457e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2458e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2459e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2460f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbournestatic void HandleOpenCLKernelAttr(Decl *d, const AttributeList &Attr, Sema &S){
2461f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  assert(Attr.isInvalid() == false);
2462f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  d->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2463f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2464f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2465711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2466711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2467711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2468711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2469831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
2470831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2471831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
2472711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2473711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2474711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2475ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
247655d3aaf9a537888734762170823daf750ea9036dEli Friedman
2477414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
2478414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
2479711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2480711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
2481711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2482711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2483711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2484711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2485414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2486414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2487414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2488414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (Str == 0 || Str->isWide()) {
2489414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2490414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2491414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2492414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
2493414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2494414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2495414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    llvm::StringRef StrRef = Str->getString();
2496414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
2497414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
2498414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2499414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
2500414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
2501414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2502414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2503414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
2504414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2505711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
2506711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2507711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2508711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2509711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2510711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2511711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleRegparmAttr(Decl *d, const AttributeList &attr, Sema &S) {
2512711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (hasDeclarator(d)) return;
2513711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2514711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
2515711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckRegparmAttr(attr, numParams))
2516711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2517711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2518711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (!isa<ObjCMethodDecl>(d)) {
2519711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2520883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
2521ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2522ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
252355d3aaf9a537888734762170823daf750ea9036dEli Friedman
2524711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  d->addAttr(::new (S.Context) RegparmAttr(attr.getLoc(), S.Context, numParams));
2525711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2526711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2527711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
2528711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
2529711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckRegparmAttr(const AttributeList &attr, unsigned &numParams) {
2530711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2531711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2532711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2533711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.getNumArgs() != 1) {
2534711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2535711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2536711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2537711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2538711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2539711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  Expr *NumParamsExpr = attr.getArg(0);
254055d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2541ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2542711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
2543711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_argument_not_int)
254455d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
2545711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2546711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
254755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
254855d3aaf9a537888734762170823daf750ea9036dEli Friedman
2549711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (Context.Target.getRegParmMax() == 0) {
2550711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
255155d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
2552711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2553711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
255455d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
255555d3aaf9a537888734762170823daf750ea9036dEli Friedman
2556711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
2557711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (numParams > Context.Target.getRegParmMax()) {
2558711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2559711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
2560711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2561711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
256255d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
256355d3aaf9a537888734762170823daf750ea9036dEli Friedman
2564711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2565ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2566ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
25677b381985353304a7723acb05911ff91634fa1f27Peter Collingbournestatic void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){
25687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
25697b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
25707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
2571bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
2572bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
25737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
25747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
25757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
25767b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (!isFunctionOrMethod(d)) {
25777b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2578883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
25797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
25807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
25817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
25827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
25837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
25847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
25857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
25867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
25877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
25887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
25897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
25907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
25917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
25927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
25937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
25947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
25957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
25967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
25977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
25987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
25997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
26007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
26017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
26027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
26057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
26067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
26077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
26087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
26097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
26107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
26117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
2613b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
2614b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
2615b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2616c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
2617c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
2618c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2619c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
2620c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
2621c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2622c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2623c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSConsumedAttr(Decl *d, const AttributeList &attr, Sema &S) {
2624c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  ParmVarDecl *param = dyn_cast<ParmVarDecl>(d);
2625c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
2626c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2627883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << SourceRange(attr.getLoc()) << attr.getName() << ExpectedParameter;
2628c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2629c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2630c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2631c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
2632c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (attr.getKind() == AttributeList::AT_ns_consumed) {
2633c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
2634c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2635c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
2636c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
2637c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2638c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2639c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2640c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
2641c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
2642c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << SourceRange(attr.getLoc()) << attr.getName() << cf;
2643c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2644c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2645c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2646c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
2647c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    param->addAttr(::new (S.Context) CFConsumedAttr(attr.getLoc(), S.Context));
2648c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
2649c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    param->addAttr(::new (S.Context) NSConsumedAttr(attr.getLoc(), S.Context));
2650c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2651c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2652c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSConsumesSelfAttr(Decl *d, const AttributeList &attr,
2653c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                     Sema &S) {
2654c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!isa<ObjCMethodDecl>(d)) {
2655c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2656883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << SourceRange(attr.getLoc()) << attr.getName() << ExpectedMethod;
2657c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2658c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2659c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2660c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  d->addAttr(::new (S.Context) NSConsumesSelfAttr(attr.getLoc(), S.Context));
2661c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2662c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2663c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &attr,
2664b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek                                        Sema &S) {
2665b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2666c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
2667bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
26685dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
2669c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
26705dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
2671c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
26725dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
267321531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2674c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall        << SourceRange(attr.getLoc()) << attr.getName()
2675883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
2676b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
2677b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
2678bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2679c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
2680c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
2681c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  switch (attr.getKind()) {
2682c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
2683c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
2684c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
2685c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
2686c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
2687c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2688c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2689c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2690c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
2691c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
2692c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
2693c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2694c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2695c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2696c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2697c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
269821531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
2699c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << SourceRange(attr.getLoc())
2700c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << attr.getName() << isa<ObjCMethodDecl>(d) << cf;
2701bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
27025dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
2703bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2704c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  switch (attr.getKind()) {
2705b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
2706b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
2707b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2708c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
2709c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(attr.getLoc(),
2710c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
2711c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
271231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
2713c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(attr.getLoc(),
2714f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
271531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
271631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
2717c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(attr.getLoc(),
2718f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
271931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
2720b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
2721c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) CFReturnsRetainedAttr(attr.getLoc(),
2722f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2723b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2724b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
2725c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) NSReturnsRetainedAttr(attr.getLoc(),
2726f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2727b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2728b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
2729b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
2730b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2731f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2732f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
273311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
273411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
273511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
273611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
273711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
273811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
273911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
274011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
274111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichetstatic void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) {
274211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
274311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
274411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    if (Attr.getNumArgs() != 1) {
274511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
274611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
274711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    }
274811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
274911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2750d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (Str == 0 || Str->isWide()) {
2751d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2752d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
2753d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2754d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2755d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2756d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    llvm::StringRef StrRef = Str->getString();
2757d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2758d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
2759d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
2760d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2761d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
2762d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
2763d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2764d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2765d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2766d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
2767d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2768d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2769d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2770d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2771d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
2772d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
2773f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    llvm::StringRef::iterator I = StrRef.begin();
2774f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
2775f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
2776f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
2777f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
2778d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
2779d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
2780d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2781d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
2782d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
2783d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
2784d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2785d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
2786d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
2787d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
2788d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
278911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
279011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    d->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
279111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
2792d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
279311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
2794f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
2795f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
2796b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
27970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
27980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
27990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
280060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessNonInheritableDeclAttr(Scope *scope, Decl *D,
280160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                          const AttributeList &Attr, Sema &S) {
280260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
280360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:      HandleDeviceAttr      (D, Attr, S); break;
280460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:        HandleHostAttr        (D, Attr, S); break;
280560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
280660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
280760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
280860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
280960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
2810e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
281160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessInheritableDeclAttr(Scope *scope, Decl *D,
281260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                       const AttributeList &Attr, Sema &S) {
2813803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
281463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  case AttributeList::AT_IBAction:            HandleIBAction(D, Attr, S); break;
2815857e918a8a40deb128840308a318bf623d68295fTed Kremenek    case AttributeList::AT_IBOutlet:          HandleIBOutlet(D, Attr, S); break;
2816857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
2817857e918a8a40deb128840308a318bf623d68295fTed Kremenek      HandleIBOutletCollection(D, Attr, S); break;
2818803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
2819207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
2820ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
28216e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
28224211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
28234211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
2824bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
2825bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
2826803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
282760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
282860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
282960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
283060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
283160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
283260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
28337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_alias:       HandleAliasAttr       (D, Attr, S); break;
28347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_aligned:     HandleAlignedAttr     (D, Attr, S); break;
2835bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
2836af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
2837b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
2838bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
28397725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_annotate:    HandleAnnotateAttr    (D, Attr, S); break;
28400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  case AttributeList::AT_availability:HandleAvailabilityAttr(D, Attr, S); break;
2841bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
28427725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                      HandleDependencyAttr  (D, Attr, S); break;
2843a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  case AttributeList::AT_common:      HandleCommonAttr      (D, Attr, S); break;
2844ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_constant:    HandleConstantAttr    (D, Attr, S); break;
28457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
28467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_deprecated:  HandleDeprecatedAttr  (D, Attr, S); break;
28477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_destructor:  HandleDestructorAttr  (D, Attr, S); break;
28483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
28499cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    HandleExtVectorTypeAttr(scope, D, Attr, S);
28503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
28517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format:      HandleFormatAttr      (D, Attr, S); break;
28527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format_arg:  HandleFormatArgAttr   (D, Attr, S); break;
2853ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_global:      HandleGlobalAttr      (D, Attr, S); break;
28547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr   (D, Attr, S); break;
28557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
28567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    HandleLaunchBoundsAttr(D, Attr, S);
28577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
28587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_mode:        HandleModeAttr        (D, Attr, S); break;
28597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_malloc:      HandleMallocAttr      (D, Attr, S); break;
286034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  case AttributeList::AT_may_alias:   HandleMayAliasAttr    (D, Attr, S); break;
2861a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  case AttributeList::AT_nocommon:    HandleNoCommonAttr    (D, Attr, S); break;
28627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nonnull:     HandleNonNullAttr     (D, Attr, S); break;
2863dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
2864dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
2865dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
2866dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      HandleOwnershipAttr     (D, Attr, S); break;
2867dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  case AttributeList::AT_naked:       HandleNakedAttr       (D, Attr, S); break;
28687725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;
28697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;
2870ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_shared:      HandleSharedAttr      (D, Attr, S); break;
287135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  case AttributeList::AT_vecreturn:   HandleVecReturnAttr   (D, Attr, S); break;
2872b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2873b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
2874c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
2875c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumed: HandleNSConsumedAttr  (D, Attr, S); break;
2876c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
2877c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    HandleNSConsumesSelfAttr(D, Attr, S); break;
2878c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2879c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
288031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
288131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
2882b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
2883b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
2884b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    HandleNSReturnsRetainedAttr(D, Attr, S); break;
2885b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
28866f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
28876f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    HandleReqdWorkGroupSize(D, Attr, S); break;
28886f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
2889521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
2890521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      HandleInitPriorityAttr(D, Attr, S); break;
2891521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
28927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_packed:      HandlePackedAttr      (D, Attr, S); break;
28937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_section:     HandleSectionAttr     (D, Attr, S); break;
28947725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
28957725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unused:      HandleUnusedAttr      (D, Attr, S); break;
28967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_used:        HandleUsedAttr        (D, Attr, S); break;
28977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_visibility:  HandleVisibilityAttr  (D, Attr, S); break;
2898026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
2899026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
29007725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak:        HandleWeakAttr        (D, Attr, S); break;
290111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  case AttributeList::AT_weakref:     HandleWeakRefAttr     (D, Attr, S); break;
29027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak_import: HandleWeakImportAttr  (D, Attr, S); break;
2903803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
2904803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
2905803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
29060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
29070db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
29080db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
2909d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
2910d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    HandleObjCMethodFamilyAttr(D, Attr, S);
2911d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
29127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nsobject:    HandleObjCNSObject    (D, Attr, S); break;
29137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_blocks:      HandleBlocksAttr      (D, Attr, S); break;
29147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_sentinel:    HandleSentinelAttr    (D, Attr, S); break;
29157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_const:       HandleConstAttr       (D, Attr, S); break;
29167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_pure:        HandlePureAttr        (D, Attr, S); break;
29177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_cleanup:     HandleCleanupAttr     (D, Attr, S); break;
29187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nodebug:     HandleNoDebugAttr     (D, Attr, S); break;
29197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noinline:    HandleNoInlineAttr    (D, Attr, S); break;
29207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_regparm:     HandleRegparmAttr     (D, Attr, S); break;
2921bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
292205f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
292305f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
29247255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
29257255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    HandleNoInstrumentFunctionAttr(D, Attr, S);
29267255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
292704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
292804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
292904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
2930f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
293152fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2932414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
2933e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    HandleCallConvAttr(D, Attr, S);
293404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
2935f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
2936f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    HandleOpenCLKernelAttr(D, Attr, S);
2937f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
293811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
293911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    HandleUuidAttr(D, Attr, S);
294011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
2941803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
294282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
294382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
294482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
29457d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
29467d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
2947803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
2948803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2949803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2950803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
295160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
295260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
295360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
295460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
295560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessDeclAttribute(Scope *scope, Decl *D,
295660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 const AttributeList &Attr, Sema &S,
295760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
295860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
295960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
296060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
296160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
296260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
296360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
296460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
296560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
296660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessNonInheritableDeclAttr(scope, D, Attr, S);
296760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
296860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
296960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessInheritableDeclAttr(scope, D, Attr, S);
297060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
297160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
2972803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
2973803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
2974f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
297560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
297660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
297711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
297860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttribute(S, D, *l, *this, NonInheritable, Inheritable);
297911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
298011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
298111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
298211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
298311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
298460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
298511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
2986dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
298711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
2988803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2989803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2990803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
2991e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
2992e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
29931eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
29947b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
2995e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
2996e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
2997e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
2998ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                FD->getInnerLocStart(),
2999e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
3000a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
3001b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
3002b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
3003c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3004b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3005e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3006e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3007ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3008a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
300916573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
301016573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3011b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3012b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3013c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3014b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3015e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3016e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3017e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3018e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3019e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3020e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
30217b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3022c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3023c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3024c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3025c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3026c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
3027cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3028cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3029cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3030c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3031c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3032c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3033c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3034c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3035c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3036c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3037c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3038cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3039e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3040e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3041e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
30420744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
30430744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
30440744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
304560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
304660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3047d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3048d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
304960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && !WeakUndeclaredIdentifiers.empty()) {
3050d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall    if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
3051d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall      if (IdentifierInfo *Id = ND->getIdentifier()) {
3052d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
3053d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          = WeakUndeclaredIdentifiers.find(Id);
3054d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
3055d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakInfo W = I->second;
3056d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          DeclApplyPragmaWeak(S, ND, W);
3057d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakUndeclaredIdentifiers[Id] = W;
3058d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3059e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3060e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3061e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3062e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
30630744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
30647f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
306560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3066bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
30670744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
30680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
30690744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
30700744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
30710744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
30720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
307360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3074bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
30750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
30760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
307760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
30780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
307954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3080eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3081eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3082eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3083eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3084eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3085eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3086eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3087eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3088eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3089eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3090eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3091eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3092eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3093eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3094eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3095eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3096eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3097eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3098eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3099eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3100eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
310154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
310254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3103eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3104eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
3105eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
310654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3107eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
3108eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
3109eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
3110eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
311154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3112eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
3113eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
311454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3115eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
3116eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
3117eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
311858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
31192f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
31202f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
3121eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (decl) {
3122eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
3123eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
31242f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
31252f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
31262f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
31272f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
31282f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
3129eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3130eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
3131eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
31322f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
31332f514480c448708ec382a684cf5e035d3a827ec8John McCall
3134eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
31352f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
3136eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
31372f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
31382f514480c448708ec382a684cf5e035d3a827ec8John McCall
31392f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
3140eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
31412f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
314254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
314354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
314454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
314554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
314658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
3147eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
314829233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
314958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
3150eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
31512f514480c448708ec382a684cf5e035d3a827ec8John McCall}
31522f514480c448708ec382a684cf5e035d3a827ec8John McCall
31532f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
31542f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
31550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
31562f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
31572f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
31582f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
31592f514480c448708ec382a684cf5e035d3a827ec8John McCall}
31602f514480c448708ec382a684cf5e035d3a827ec8John McCall
31619c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
31622f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
31632f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
31642f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
31652f514480c448708ec382a684cf5e035d3a827ec8John McCall
31662f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
3167ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
3168c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
3169ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
3170ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
3171c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
3172c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
3173ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
317454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
317554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3176ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramervoid Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
31778e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
3178743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne                                  bool UnknownObjCClass) {
317954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
3180eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3181eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
318254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
318354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
318454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
318554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
318654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
318754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
3188ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
3189c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3190c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
31918e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
3192743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
31938e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
31948e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian    else
31958e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
31968e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
319754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
3198