SemaDeclAttr.cpp revision 1b03c8719e2e45cf2769430335d7e71f18e6634a
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//                     The LLVM Compiler Infrastructure
46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source
66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details.
76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//  This file implements decl-related attribute processing.
116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h"
1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h"
166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h"
17384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
18acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
20f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h"
21fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2219510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
239c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
24797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
269c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of
29883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
30883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCallenum {
31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunction,
32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedUnion,
33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableOrFunction,
34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionOrMethod,
35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameter,
36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedParameterOrMethod,
37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrBlock,
38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassOrVirtualMethod,
39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedFunctionMethodOrParameter,
40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClass,
41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVirtualMethod,
42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedClassMember,
43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariable,
44883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedMethod,
45883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall  ExpectedVariableFunctionOrLabel
46883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall};
47883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall
48e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
49e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
5287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D,
53a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
5587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
5987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
63bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
656217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
66755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
68d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
69183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
723568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
75d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
76a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
7787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) {
7887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return getFunctionType(D, false) != NULL;
79a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
82d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
8487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) {
8587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isFunction(D)|| isa<ObjCMethodDecl>(D);
86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
88620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
9187c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
9287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isFunctionOrMethod(D))
93620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
9587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
9987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<BlockDecl>(D);
100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
101620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
102711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
10487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) {
105f85e193739c953358c865005855253af4f68a497John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
10687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
10787c44604325578b8de07d768391c1c9432404f5aChandler Carruth         isa<ObjCPropertyDecl>(D);
108711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
110d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
111d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
112620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
11387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) {
11487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
11572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
116620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
11787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
118d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
119d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
1203568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1213568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
122d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
123d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
12587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) {
12687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
12772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
12887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
129d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
13087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_size();
1313568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
13487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
13572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
13687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
137d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
1403568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1413568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
14287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) {
14387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D))
1445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
14587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  return cast<ObjCMethodDecl>(D)->getResultType();
1465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
14887c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) {
14987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionType *FnTy = getFunctionType(D)) {
15072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
15287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
153db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
154d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
15587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    return cast<ObjCMethodDecl>(D)->isVariadic();
1563568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
15987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) {
16087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
16107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
16207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
166183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
167b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
169bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
170506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
171506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
174506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
175bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
181085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1826217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
183085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
184085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1866217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
187085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
189bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
191465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
192085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
197e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
198e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
199e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
200e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
2013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
2023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
2033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
2043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
2051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
2061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
20787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
208545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
209803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
210545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
2149cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2159cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
2169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2179cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
2189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
219f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
220f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
221f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
2224ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
2234ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
2244ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    if (Size.isInvalid())
2254ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor      return;
2264ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor
2274ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor    sizeExpr = Size.get();
2289cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
2299cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
2309cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    if (Attr.getNumArgs() != 1) {
2319cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2329cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
2339cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    }
2347a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
2356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2369cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2379cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
2389cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
2399ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
2409cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
241ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
242a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
243bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2449cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
2459cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
2466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
251545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
255bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
257cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
25887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
2596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
262803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
263fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
26408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
2656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
266cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
27287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (TagDecl *TD = dyn_cast<TagDecl>(D))
273c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    TD->addAttr(::new (S.Context) MsStructAttr(Attr.getLoc(), S.Context));
274c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian  else
275c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
276c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian}
277c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian
2781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
27996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
28096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
2813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
28296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
28396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
284bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
28563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
28687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
28763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
28887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
28963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
29063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
29163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
2924ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
29363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
29463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
2951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
29663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
29763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (Attr.getNumArgs() > 0) {
29863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
29963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
30063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  }
30163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
30263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
303efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
30487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D)) {
30587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
30663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
307efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
30863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
3094ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
31096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
31196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
3121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D,
3131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
314857e918a8a40deb128840308a318bf623d68295fTed Kremenek
315857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
316a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
317857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
318857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
319857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
320857e918a8a40deb128840308a318bf623d68295fTed Kremenek
321857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
322857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
32387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!(isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
3244ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
325857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
326857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
32787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
3283a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
3293a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
3303a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
3313a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
3323a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
33387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
3343a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
3353a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
3363a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
3373a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
3383a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
3393a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
340a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
341a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
342a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
3433a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
344b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
34587c44604325578b8de07d768391c1c9432404f5aChandler Carruth                        S.getScopeForContext(D->getDeclContext()->getParent()));
346a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
347a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
348a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
349a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
350b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
351a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
352a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
353a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
354a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
355a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
356a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
357a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
358a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
359a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
36087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
361cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
362857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
363857e918a8a40deb128840308a318bf623d68295fTed Kremenek
364d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) {
36568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian  if (const RecordType *UT = T->getAsUnionType())
36668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
36768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      RecordDecl *UD = UT->getDecl();
36868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      for (RecordDecl::field_iterator it = UD->field_begin(),
36968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian           itend = UD->field_end(); it != itend; ++it) {
37068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        QualType QT = it->getType();
37168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
37268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          T = QT;
37368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian          return;
37468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian        }
37568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian      }
37668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian    }
37768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian}
37868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
3791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
380bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
381bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
38287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
383fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
384883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
385eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
386eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
387bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
38807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
38907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
39087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
39187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
392eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
393eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
394eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
395bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
396eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
397eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
398bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
399bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
400eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
4017a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
402eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
403ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
404ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
405fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
406fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
407eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
408eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
409bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
410eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
412eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
413fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
41430bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
415eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
416eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
417bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
418465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
41907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
42007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
42107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
42207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
42307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
42407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
42507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
42607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
42707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
428eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
429eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
43087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
431d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth    possibleTransparentUnionPointerType(T);
43268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian
433dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
434eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
435c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
436fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
4377fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
438eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
439bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
440eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
441eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
442bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
443bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
444bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
4457fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
44687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
44787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
448d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth      possibleTransparentUnionPointerType(T);
449dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
450d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
45146bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
452bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
453ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
45460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
45560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
45660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
45760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
45860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
4597fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
46060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
461eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
4627fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
4637fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
4647fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
465dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
46687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
467cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
468eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
469eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
4701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
471dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
472dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
473dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
475dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
476dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
4772a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
4782a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
482dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
483dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
484dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
485dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
486cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
4872a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
4882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
489cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
490dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
491dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
492dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
493dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4942a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4952a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
496cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
497dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
498dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5012a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
5022a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
503cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
504dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
505dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
506dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
508dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5092a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
5102a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
5112a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
5122a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
513dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
514dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
51587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunction(D) || !hasFunctionProto(D)) {
516883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
517883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << AL.getName() << ExpectedFunction;
518dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
519dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
520dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
52107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
52207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
52387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
52487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
525dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
526dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::StringRef Module = AL.getParameterName()->getName();
527dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
528dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
530dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
531dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
532dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::SmallVector<unsigned, 10> OwnershipArgs;
533dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
5342a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
5352a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
536dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
5377a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
538dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
539dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
540dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
541dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
542dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
543dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
544dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
545dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
546dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
547dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
548dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
550dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
551dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
552dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
553dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
55407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
55507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
55607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
55707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
55807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
55907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
56007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
56107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
56207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
563dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
564cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
565cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
566dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
56787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      QualType T = getFunctionOrMethodArgType(D, x);
568dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
570dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
571cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
572dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
573dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
574dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
575dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
576dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
577dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
578cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
579dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
580dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
5817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
582dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
583dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
584dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
585dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
586dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
587dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
588dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
589dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
590dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
591dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
592dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5932a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
5942a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
595dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
596dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
597dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
598cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
59987c44604325578b8de07d768391c1c9432404f5aChandler Carruth          i = D->specific_attr_begin<OwnershipAttr>(),
60087c44604325578b8de07d768391c1c9432404f5aChandler Carruth          e = D->specific_attr_end<OwnershipAttr>();
601cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
602cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
603cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
604cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
605cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
606cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
607cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
608dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
609dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
610dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
611dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
612dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
613dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
614dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
615dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
616dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
617dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
618cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
619cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
620cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
621cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
622dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
623cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
62487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
625cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
626dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
627dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
628332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
629332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
630332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
631332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
632332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
633332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
634332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
635332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
636332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
637332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
638332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
639332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
640332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
641332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
642332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
643332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
644332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
64511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
64611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
64711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
6481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
64911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
65011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
65111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
65211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
65311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
65411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
65587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
656332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
657883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
658332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
659332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
660332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
66187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
662332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
66311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
66411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
66511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
66611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
66711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
66811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
66911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
67011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
67111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
67211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
67387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
6747a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
6757a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
676332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
6777a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
67811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
67911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
68011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
68111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
68211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
68311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
68411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
68511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
68611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
68711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
68811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
68911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
69011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
69111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
69211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
69311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
69411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
69511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
69611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
69711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
698332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
699332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
70011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
70111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
70211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
70311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
70411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
70511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
70611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
70711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
7087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
70911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
71011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
71111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
71211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    if (Str == 0 || Str->isWide()) {
71311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
71411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
71511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
71611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
71711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
71811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
71987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
720f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
72111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
72211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
72387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
72411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
72511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
7261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
728545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
7293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
7306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7337a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
7356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
736bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
7376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
738fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
7393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
7406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
742bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
743db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar  if (S.Context.Target.getTriple().isOSDarwin()) {
744f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
745f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
746f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
747f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
7486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
749bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
75087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
751f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
7526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
755dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
756dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  if (Attr.getNumArgs() != 0) {
757dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
758dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
759dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
760dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
76187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
762dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
763883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
764dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
765dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
766dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
76787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
768dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
769dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
7701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
7711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
772dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
773831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
7743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
775af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
776af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
7775bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
77887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
7795bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
780883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
7815bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
7825bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
783bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
78487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
785af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
786af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
7871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
788dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
789831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
79076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
79176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
79276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
7931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
79487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
7962cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
79787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
7982cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
7992cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
800fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
801fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
8022cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
80376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
80476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
8051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
80634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
80734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  if (Attr.getNumArgs() != 0) {
80834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
80934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
81034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  }
81134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
81287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
81334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
81434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
8151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
816a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
81787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
81887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
819722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
820722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
821883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
822a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
823a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
8241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
825a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
82687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (isa<VarDecl>(D))
82787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
828722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
829722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
830883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariable;
831a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
832a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
8331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
83487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
835711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
836711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
837711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
83887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
839711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
840883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << attr.getName() << ExpectedFunctionOrMethod;
841711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
842711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
843711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
84487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
845711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
846711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
847711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
848831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (attr.hasParameterOrArguments()) {
849711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
850711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
851711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
852711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
853711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
854711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
855b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
856b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
8571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
8581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
859b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
860b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
861b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
862b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
863545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
864e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
865b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek    return;
8666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
867b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
86887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
86987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    ValueDecl *VD = dyn_cast<ValueDecl>(D);
8703ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
8713ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
872e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
873e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
874b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
875883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
876b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
87719c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
8786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
879b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
88087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
8816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
88335cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
8841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
88535cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
88635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
88735cc9627340b15232139b3c43fcde5973e7fad30John Thompson
888f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
889f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
890f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
891f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
892f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
89335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
89435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
89535cc9627340b15232139b3c43fcde5973e7fad30John Thompson
89635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
89735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
89835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
89935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
90035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
90135cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
90235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
90335cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
90435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
90535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
90635cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
90735cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
90887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<RecordDecl>(D)) {
90935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
910883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedClass;
91135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
91235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
91335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
91487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (D->getAttr<VecReturnAttr>()) {
91535cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
91635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
91735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
91835cc9627340b15232139b3c43fcde5973e7fad30John Thompson
91987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  RecordDecl *record = cast<RecordDecl>(D);
92001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
92101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
92201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
92301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
92401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
92501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
92601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
92701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
92801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
92901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
93001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
93101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
932f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
933f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
93401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
93501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
93601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
93701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
93801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
93901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
94001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
94187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
94235cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
94335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
9441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
94587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
946bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
947883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrParameter;
948bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
949bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
950bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
951bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
952bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
9531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
95473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
955831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
9563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
95773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
95873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
959bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
96087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
96187c44604325578b8de07d768391c1c9432404f5aChandler Carruth      !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
962fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
963883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableFunctionOrLabel;
96473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
96573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
966bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
96787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
96873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
96973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
9701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
971b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
972831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
973b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
974b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
975b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
976bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
97787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
978186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
979b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
980b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
981b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
98287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (!isFunctionOrMethod(D)) {
983b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
984883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedVariableOrFunction;
985b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
986b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
987bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
98887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
989b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
990b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
9911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
9923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
993bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
994bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
9953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
996bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
9973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
9993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
10007a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
10013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1002ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1003ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1004fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
10063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
10073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
10083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
10093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1010bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
101187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1012fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1013883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
10143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
10153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
10163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
101787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
1018f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
10193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
10203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
10223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
1023bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall  if (Attr.getNumArgs() > 1) {
1024bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
10253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
1026bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
10273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
10293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
10307a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
10313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
1032ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1033ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1034fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
10363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
10373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
10383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
10393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1040bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
104187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
1042fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1043883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
10443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
10453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
10463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
104787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1048f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
10493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
10503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
10511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1052951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1053951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1054bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1055c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1056c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1057951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1058c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
1059951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  llvm::StringRef Str;
1060951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1061951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1062c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1063951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1064951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner        << "deprecated";
1065c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1066c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
1067951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
10686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1069bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
107087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
10716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1074951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  unsigned NumArgs = Attr.getNumArgs();
1075951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs > 1) {
1076bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1077bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1078bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1079951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner
1080c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
1081951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  llvm::StringRef Str;
1082951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner  if (NumArgs == 1) {
1083951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1084c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1085951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner      S.Diag(Attr.getArg(0)->getLocStart(),
1086c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1087c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1088c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1089951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner    Str = SE->getString();
1090c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
109187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
1092bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1093bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
10941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D,
10951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
10960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  IdentifierInfo *Platform = Attr.getParameterName();
10970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  SourceLocation PlatformLoc = Attr.getParameterLoc();
10980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
10990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  llvm::StringRef PlatformName
11000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
11010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (PlatformName.empty()) {
11020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
11030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << Platform;
11040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    PlatformName = Platform->getName();
11060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
11090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
11100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1111b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
11120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // Ensure that Introduced < Deprecated < Obsoleted (although not all
11140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  // of these steps are needed).
11150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Deprecated.isValid() &&
11160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Deprecated.Version)) {
11170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
11180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << PlatformName << Deprecated.Version.getAsString()
11190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
11200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Introduced.isValid() && Obsoleted.isValid() &&
11240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Introduced.Version < Obsoleted.Version)) {
11250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
11260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
11270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 0 << Introduced.Version.getAsString();
11280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (Deprecated.isValid() && Obsoleted.isValid() &&
11320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      !(Deprecated.Version < Obsoleted.Version)) {
11330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
11340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 2 << PlatformName << Obsoleted.Version.getAsString()
11350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      << 1 << Deprecated.Version.getAsString();
11360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return;
11370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
11380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
113987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
11400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Platform,
11410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Introduced.Version,
11420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor                                                Deprecated.Version,
1143b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                Obsoleted.Version,
1144b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor                                                IsUnavailable));
11450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor}
11460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
11471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
11486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1149545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
11503c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11547a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
11556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
11566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1157bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
1159fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
11603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
11616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1163bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1164c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  llvm::StringRef TypeStr = Str->getString();
1165cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1167c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1168cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1169c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1170cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1171c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1172cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1173c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1174cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
11756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
117608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
11776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1179bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
118087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
11816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
11841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
1185d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1186d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (!method) {
118787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1188883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << ExpectedMethod;
1189d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1190d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1191d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
119287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
119387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
119487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1195d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall        << "objc_method_family" << 1;
1196d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    } else {
119787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1198d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
119987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
1200d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1201d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1202d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
120387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  llvm::StringRef param = Attr.getParameterName()->getName();
1204d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  ObjCMethodFamilyAttr::FamilyKind family;
1205d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (param == "none")
1206d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_None;
1207d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "alloc")
1208d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_alloc;
1209d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "copy")
1210d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_copy;
1211d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "init")
1212d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_init;
1213d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "mutableCopy")
1214d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1215d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else if (param == "new")
1216d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    family = ObjCMethodFamilyAttr::OMF_new;
1217d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  else {
1218d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // Just warn and ignore it.  This is future-proof against new
1219d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // families being used in system headers.
122087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1221d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return;
1222d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
1223d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
1224f85e193739c953358c865005855253af4f68a497John McCall  if (family == ObjCMethodFamilyAttr::OMF_init &&
1225f85e193739c953358c865005855253af4f68a497John McCall      !method->getResultType()->isObjCObjectPointerType()) {
1226f85e193739c953358c865005855253af4f68a497John McCall    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1227f85e193739c953358c865005855253af4f68a497John McCall      << method->getResultType();
1228f85e193739c953358c865005855253af4f68a497John McCall    // Ignore the attribute.
1229f85e193739c953358c865005855253af4f68a497John McCall    return;
1230f85e193739c953358c865005855253af4f68a497John McCall  }
1231f85e193739c953358c865005855253af4f68a497John McCall
123287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getLoc(),
1233f85e193739c953358c865005855253af4f68a497John McCall                                                       S.Context, family));
1234d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall}
1235d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
12361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
12371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
12380db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
12390db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
12400db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
12410db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1242bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12430db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
12440db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
12450db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
12460db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
12470db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1248bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1249cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
12500db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
12510db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
12521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1253fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
12542b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1255fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1256fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1257162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1258fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1259fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
12606217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1261fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1262fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1263fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1264fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1265cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1266fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1267fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1268bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
12691b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1270f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
12712b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1272f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1273f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1274f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1275f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1276f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1277f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1278f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1279f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1280cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1281f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1282f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
12831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1284bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1285fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
12879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
12889eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1289bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12909eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
12913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12929eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
12939eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1294bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1295cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
129692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
12979eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
12989eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1299fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
13003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
13019eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
13029eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1303bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
130487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
13059eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
13069eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
13071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1308770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1309770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1310bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1311770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1312bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1313bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1314770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1315770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
13167a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1317770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1318ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1319ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1320fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1322770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1323770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1324770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1325bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1326770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1327fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1328fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1329770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1330770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1331770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1332770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1333770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1334770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
13357a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1336770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1337ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1338ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1339fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1341770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1342770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1343770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1344bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1345770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1346770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1347770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1348fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1349fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1350770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1351770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1352770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1353770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
135487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1355183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1356897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1357bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1358897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1359897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1360897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1361897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1362bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1363897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
13643bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1365770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1366bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
136787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1368770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
13693bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1370770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
13712f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
137287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (isa<BlockDecl>(D)) {
1373bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1374bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
13752f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
137687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
13772f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1378daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
137987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1380f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
13812f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
13823bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
13833bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
13842f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
13852f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1386ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
13872f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1388883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionMethodOrBlock;
13892f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
13902f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1391770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1392fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1393883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionMethodOrBlock;
1394770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1395770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
139687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1397f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1398770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1399770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
14001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1401026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
1402026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
1403026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1404026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1405026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1406026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1407f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1408026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1409883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunctionOrMethod;
1410026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1411026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1412bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1413f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1414f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1415f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1416f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1417f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1418f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1419f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1420f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1421f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1422f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1423f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1424f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1425cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1426026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1427026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
14281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
143087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.hasParameterOrArguments()) {
143187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
14326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
14346e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
143587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
143687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
143787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedVariableOrFunction;
1438f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1439f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1440f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
144187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  NamedDecl *nd = cast<NamedDecl>(D);
1442332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1443332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1444332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
144587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
14466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
14476e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1448bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
144987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  nd->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
14506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
14536e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
14546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
14556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
14566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
1457bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
14586e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
14596e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
14606e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
14610a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (!D->canBeWeakImported(isDef)) {
14620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (isDef)
14630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      S.Diag(Attr.getLoc(),
14640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor             diag::warn_attribute_weak_import_invalid_on_definition)
14650a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        << "weak_import" << 2 /*variable and function*/;
1466def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1467db57a4cdb0a6abf3239f3a794a900ce312c5887bDaniel Dunbar             (S.Context.Target.getTriple().isOSDarwin() &&
1468def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor              isa<ObjCInterfaceDecl>(D))) {
1469def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor      // Nothing to warn about here.
1470def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor    } else
1471c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1472883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
14736e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
14746e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
14756e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
14766e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1477cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
14786e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
14796e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
14801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D,
14811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
14826f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
14836f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  if (Attr.getNumArgs() != 3) {
1484a8581b9ca06e6ad504af2e28c0798520364f7f1bChandler Carruth    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
14856f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
14866f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
14876f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
14886f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
14896f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
14907a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
14916f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1492ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1493ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
14946f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
14956f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
14966f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
14976f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
14986f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
14996f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1500cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1501cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
15026f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
15036f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
15046f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
15051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
150617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
150717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
150817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
150917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
151017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
151117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
151217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
151317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
15147a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1515797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
151617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1517797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
151817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
151917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
15201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1521797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1522bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1523a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1524a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1525a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1526797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1527797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
15281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1529a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1530a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1531a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1532a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1533a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1534a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1535f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1536f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
153717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
153817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
15396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
15416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1542831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
15433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
15446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
15456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1546b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
154787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
1548b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (Existing->getLocation().isInvalid())
1549b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      Existing->setLocation(Attr.getLoc());
1550b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
155187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
1552b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
15536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
15546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
15551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1556232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1557831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if (Attr.hasParameterOrArguments()) {
15583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1559232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1560232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1561bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
156287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
1563b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor   if (Existing->getLocation().isInvalid())
1564b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor     Existing->setLocation(Attr.getLoc());
1565b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  } else {
156687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1567b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
1568232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1569232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
15701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1571232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1572232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
15733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1574232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1575232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1576bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
157787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1578232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1579232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
15801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1581bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1582f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1583f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1584f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1585bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1586f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1587f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1588f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1589f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1590bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
159187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  VarDecl *VD = dyn_cast<VarDecl>(D);
1592bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1593f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1594f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1595f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1596f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1597bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1598f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1599c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1600f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1601f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1602f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1603f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
1604f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1605f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1606f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1607f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1608bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1609f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1610f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
1611f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1612f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
1613f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1614f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1615f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1616f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1617f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
1618f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1619f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
1620f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1621f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1622f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1623bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
162489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
162589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
162689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
162789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1628b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
1629b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
1630f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
163189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
163289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
163389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
163489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1635bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
163687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1637223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1638f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1639f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1640bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1641bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
16421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
16435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Attr.getNumArgs() != 1) {
16445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
16455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
164787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
16485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1649883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
16505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
165207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
165307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
165407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
165587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
165687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
16575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
165807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
16595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
16607a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
16615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1662ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1663ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
16645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
16655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
16665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1668bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
16705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
16715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
16725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
16735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1674bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1676bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
167707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
167807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
167907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
168007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
168107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
168207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
168307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
168407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
168507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
16865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
168787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
1688bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
16905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
16915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
16925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
16936217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
16945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
16955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1696bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
16975b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
16985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1699bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
170087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Ty = getFunctionOrMethodResultType(D);
17015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
17025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
17035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
17046217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
17055b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
17065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1707bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
17085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
17095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1710bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1711bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
171287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
171307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
17145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
17155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
17162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
17172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
17182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
17192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
17202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
17213c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
17222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
17232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
17242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
17252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
17262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
17272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
17282b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
17292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
17302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
17312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
17322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
17332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
17342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
17352b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
17362b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
17372b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
17382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
17392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
1740cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "zcmn_err" ||
1741cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner      Format == "kprintf")  // OpenBSD.
17422b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
17432b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1744bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1745bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
17463c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
17473c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
17482b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
17492b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
17502b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1751521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
1752521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
17531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D,
17541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                   const AttributeList &Attr) {
1755521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
1756521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1757521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1758521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1759521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
176087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
1761b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1762b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1763b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1764b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
176587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType T = dyn_cast<VarDecl>(D)->getType();
1766b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
1767b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
1768b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
1769b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1770b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1771b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1772b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1773b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1774521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
1775521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1776521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1777521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1778521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
17797a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
1780b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1781521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
1782521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1783521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1784521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1785521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
1786521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1787521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1788521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
17899f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
1790521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
1791521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1792521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
1793521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1794521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1795521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
179687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
1797f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
1798521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
1799521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1800bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1801bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
18021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
18036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1804545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1805fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
18063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
18076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1810545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
18113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
18126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
181587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
1816fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1817883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
18186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
182107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
182207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
182387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  bool HasImplicitThisParam = isInstanceMethod(D);
182487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
18256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
18266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
182701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Format = Attr.getParameterName()->getName();
18286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
18302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
18312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
18322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
18332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
18342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
18353c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
18363c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
18373c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
18383c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
18392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1840fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
184101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
18426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
18467a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
1847803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1848ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1849ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1850fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
18513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
18526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1856fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
18573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
18586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
18626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18644a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
18654a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
186607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
186707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
186807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
18694a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
18704a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
18714a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
18724a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
18731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
187587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
18766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1878085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1879fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1880fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1881085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1882085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
18832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1884390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1885390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1886803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1887390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1888fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1889fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
18906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1891bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
18926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
18936217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1894390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1895fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1896fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
18976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
19017a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
1902803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1903ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1904ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1905fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
19063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
19076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
19116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
191287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (isFunctionOrMethodVariadic(D)) {
19136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
19146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
191587c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
19166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
19176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
19186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
19213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
19222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
19236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1924fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1925fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
19266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
19276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
19286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
19296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1930fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
19313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
19326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1935b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  // Check whether we already have an equivalent format attribute.
1936b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  for (specific_attr_iterator<FormatAttr>
193787c44604325578b8de07d768391c1c9432404f5aChandler Carruth         i = D->specific_attr_begin<FormatAttr>(),
193887c44604325578b8de07d768391c1c9432404f5aChandler Carruth         e = D->specific_attr_end<FormatAttr>();
1939b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor       i != e ; ++i) {
1940b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    FormatAttr *f = *i;
1941b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    if (f->getType() == Format &&
1942b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFormatIdx() == (int)Idx.getZExtValue() &&
1943b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->getFirstArg() == (int)FirstArg.getZExtValue()) {
1944b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // If we don't have a valid location for this attribute, adopt the
1945b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      // location.
1946b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      if (f->getLocation().isInvalid())
1947b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor        f->setLocation(Attr.getLoc());
1948b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor      return;
1949b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor    }
1950b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor  }
1951b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor
195287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1953cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
19542b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
19556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
19566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
19581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
19596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1960545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
19613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
19626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
19660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
196787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
19680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
19690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
19700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
197187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    RD = dyn_cast<RecordDecl>(D);
19720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
19730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1974fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1975883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedUnion;
19766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
19786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
19790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1980bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
19810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
19820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
19840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
198517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
198617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
19870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
19880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
19890c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1991bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
19920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
19930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
199490cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
1995bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
199690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
199790cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
19980c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
19990c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
2000bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
20010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
20020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
20030c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
20040c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
20050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
20060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
20070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
20080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2009bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
20100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
2011bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
20120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
20130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
20140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2015bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
20160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
20170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
2018bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
2019bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
2020bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
20216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2022cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
20236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2027545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
20283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
20296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
20317a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
2032797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2033bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
20346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
20356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
20366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
2037797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
20386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
204087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
2041f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
20426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
20436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
20456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
2046545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
20473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
20486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2050bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2051bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
2052bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
2053bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
20546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2055545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
2056cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
20574ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
20584ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
20594ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
20607a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
20614ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
20624ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
20634ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
20644ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
20654ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
2066cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
20676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
20686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2069bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2070cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
207149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
20724ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
20734ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
20744ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
207549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
207649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
2077396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
20784ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
20794ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
2080396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
2081396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
2082396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
2083cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2084cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
2085cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
2086cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
2087cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
2088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
2089cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
2090cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
20916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2092fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2093d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive
2094bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
2095fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
2096bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
2097bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2098bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
20991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2100fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
2101fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
2102fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2103fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
2104fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
21053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2106fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2107fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2108fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2109fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
2110fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
21110b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2112fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2113fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2114210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
211501eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Str = Attr.getParameterName()->getName();
2116fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2117fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
2118210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
2119210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
2120fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2121fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
2122fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
212373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
2124210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
2125fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
212673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
212773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
212873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
212973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
213073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
213173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
213273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
213373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
213473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
213573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
213673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
213773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
213873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
213973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
214073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
214173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2142fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2143fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
2144fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2145fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
2146210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
21470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2148210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
21490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
2150fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2151fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2152210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
21530b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2154fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2155fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2156fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2157fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2158162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2159fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2160fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2161fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2162fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2163fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2164fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2165fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2166fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
216773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2168183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
216973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
217073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
21712ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
217273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
217373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
217473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
217573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
217673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
217773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
217873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
217973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
218073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2181390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2182390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2183390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2184390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2185f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2186f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2187fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2188fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2189fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
21903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2191fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2192fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
21933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2194fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2195fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
219673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
219773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
219873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
219973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2200fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
22010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2202fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
22030b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2204fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2205fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
220673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
220773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
220873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
220973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2210fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
22110b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2212fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
22130b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2214fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2215fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2216fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
22170b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2218fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
22190b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2220fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
22210b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2222fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2223fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2224fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
22250b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2226fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2227aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2228aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2229aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2230aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2231fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2232aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2233aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2234aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2235aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2236fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
223773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
223873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
223973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2240f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2241f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2242f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2243f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2244f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2245f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2246f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2247f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2248f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
224973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2250fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2251fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
225273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
225373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2254fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2255fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2256fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2257162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2258ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2259a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2260ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2261fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2262fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
22630744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
22641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2265d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
2266d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
2267d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2268d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2269d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2270e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
227187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isFunctionOrMethod(D)) {
2272d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2273883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
2274d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2275d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2276bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
227787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2278d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2279d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
22801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
22815bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
22825bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
22835bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
22845bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
22855bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2286bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
228787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
22885bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2289883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
22905bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
22915bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2292bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
229387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
22945bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
22955bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
22961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
22971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                           const AttributeList &Attr) {
22987255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
22997255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (Attr.getNumArgs() != 0) {
23007255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
23017255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
23027255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
23037255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
230487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<FunctionDecl>(D)) {
23057255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2306883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
23077255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
23087255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
23097255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
231087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2311f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
23127255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
23137255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
23141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2315ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2316ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2317831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek    if (Attr.hasParameterOrArguments()) {
2318ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2319ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2320ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2321ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
232287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2323ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2324883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2325ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2326ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2327ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
232887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2329ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2330ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2331ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2332ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2333ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
23341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2335ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2336ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2337ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2338ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2339ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2340ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2341ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
234287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2343ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2344883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariableOrFunction;
2345ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2346ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2347ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
234887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2349ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2350ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2351ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2352ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2353ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
23541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2355ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2356ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2357ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2358ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2359ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2360ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2361ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
236287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2363ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2364883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2365ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2366ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2367ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
236887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    FunctionDecl *FD = cast<FunctionDecl>(D);
23692c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2370723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
23712c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
23722c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
23732c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
23742c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
23752c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
23762c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
23772c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
23782c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
23792c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
23802c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
23812c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
23822c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
238387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2384ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2385ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2386ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2387ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2388ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
23891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2390ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2391ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2392ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2393ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2394ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2395ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2396ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
239787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<FunctionDecl>(D)) {
2398ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2399883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunction;
2400ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2401ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2402ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
240387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2404ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2405ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2406ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2407ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2408ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
24091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2410ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2411ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2412ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2413ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2414ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2415ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2416ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
241787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isa<VarDecl>(D)) {
2418ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2419883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedVariable;
2420ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2421ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2422ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
242387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2424ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2425ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2426ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2427ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2428ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
24291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
243026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
243126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
243226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
243326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
243426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2435bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
243687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2437c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
243826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2439883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall      << Attr.getName() << ExpectedFunction;
244026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
244126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2442bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
24430130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2444cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2445c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2446c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2447bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
244887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
244926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
245026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
24511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
245287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2453711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
245487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2455e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2456711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
245787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckCallingConvAttr(Attr, CC))
2458711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2459e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
246087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
246187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
246287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2463711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2464711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2465711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
246687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2467e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
246887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2469e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2470e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
247187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2472e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2473f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
247487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
247504633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2476e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
247787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2478e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
247952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
248087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
248152fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2482414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
248387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Expr *Arg = Attr.getArg(0);
2484414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2485414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (Str == 0 || Str->isWide()) {
248687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2487414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
248887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2489414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2490414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2491414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2492414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    llvm::StringRef StrRef = Str->getString();
2493414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    PcsAttr::PCSType PCS;
2494414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs")
2495414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS;
2496414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else if (StrRef == "aapcs-vfp")
2497414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      PCS = PcsAttr::AAPCS_VFP;
2498414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    else {
249987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
250087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      Attr.setInvalid();
2501414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return;
2502414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2503414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
250487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) PcsAttr(Attr.getLoc(), S.Context, PCS));
2505414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2506e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2507e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2508e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2509e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2510e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2511e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
25121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
2513f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  assert(Attr.isInvalid() == false);
251487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2515f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2516f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2517711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2518711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2519711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2520711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2521831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek  if ((attr.getNumArgs() != 0 &&
2522831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2523831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek      attr.getParameterName()) {
2524711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2525711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2526711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2527ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
252855d3aaf9a537888734762170823daf750ea9036dEli Friedman
2529414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // TODO: diagnose uses of these conventions on the wrong target. Or, better
2530414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  // move to TargetAttributesSema one day.
2531711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2532711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
2533711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2534711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2535711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2536711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2537414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs: {
2538414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    Expr *Arg = attr.getArg(0);
2539414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2540414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (Str == 0 || Str->isWide()) {
2541414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2542414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov        << "pcs" << 1;
2543414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      attr.setInvalid();
2544414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      return true;
2545414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2546414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov
2547414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    llvm::StringRef StrRef = Str->getString();
2548414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    if (StrRef == "aapcs") {
2549414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS;
2550414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2551414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    } else if (StrRef == "aapcs-vfp") {
2552414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      CC = CC_AAPCS_VFP;
2553414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov      break;
2554414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    }
2555414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    // FALLS THROUGH
2556414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
2557711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
2558711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2559711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2560711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2561711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2562711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
25631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
256487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2565711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2566711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
256787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (S.CheckRegparmAttr(Attr, numParams))
2568711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2569711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
257087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
257187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
257287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << ExpectedFunctionOrMethod;
2573ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2574ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
257555d3aaf9a537888734762170823daf750ea9036dEli Friedman
257687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, numParams));
2577711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2578711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2579711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
2580711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
258187c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
258287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.isInvalid())
2583711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2584711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
258587c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getNumArgs() != 1) {
258687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
258787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2588711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2589711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2590711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
259187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  Expr *NumParamsExpr = Attr.getArg(0);
259255d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2593ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2594711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
259587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
259655d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
259787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2598711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
259955d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
260055d3aaf9a537888734762170823daf750ea9036dEli Friedman
2601711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (Context.Target.getRegParmMax() == 0) {
260287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
260355d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
260487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2605711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
260655d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
260755d3aaf9a537888734762170823daf750ea9036dEli Friedman
2608711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
2609711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (numParams > Context.Target.getRegParmMax()) {
261087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2611711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
261287c44604325578b8de07d768391c1c9432404f5aChandler Carruth    Attr.setInvalid();
2613711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
261455d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
261555d3aaf9a537888734762170823daf750ea9036dEli Friedman
2616711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2617ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2618ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
26191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
26207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
26217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
26227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
2623bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      // FIXME: 0 is not okay.
2624bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
26257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
26267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
262887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    if (!isFunctionOrMethod(D)) {
26297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2630883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << Attr.getName() << ExpectedFunctionOrMethod;
26317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
26327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
26357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
26367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
26377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
26387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
26397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
26407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
26417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
26427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
26457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
26467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
26477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
26487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
26497b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
26507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
26517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
26527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
26537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
26547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
26557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
265687c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
26577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
26587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
26597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
26607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
26617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
26627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
26637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
26640744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
2665b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
2666b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
2667b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2668c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
2669c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
2670c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2671c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
2672c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
2673c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2674c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
26751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
267687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
2677c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
267887c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
267987c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedParameter;
2680c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2681c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2682c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2683c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
268487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (Attr.getKind() == AttributeList::AT_ns_consumed) {
2685c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
2686c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2687c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
2688c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
2689c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2690c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2691c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2692c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
269387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
269487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << cf;
2695c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2696c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2697c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2698c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
269987c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getLoc(), S.Context));
2700c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
270187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getLoc(), S.Context));
2702c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2703c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
27041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
27051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                     const AttributeList &Attr) {
270687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<ObjCMethodDecl>(D)) {
270787c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
270887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedMethod;
2709c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2710c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2711c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
271287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getLoc(), S.Context));
2713c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2714c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
27151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
27161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                        const AttributeList &Attr) {
2717b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2718c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
2719bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
272087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2721c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
272287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
2723831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian    returnType = PD->getType();
272487c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
272587c44604325578b8de07d768391c1c9432404f5aChandler Carruth           (Attr.getKind() == AttributeList::AT_ns_returns_retained))
2726f85e193739c953358c865005855253af4f68a497John McCall    return; // ignore: was handled as a type attribute
272787c44604325578b8de07d768391c1c9432404f5aChandler Carruth  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
2728c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
27295dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
273087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
273187c44604325578b8de07d768391c1c9432404f5aChandler Carruth        << SourceRange(Attr.getLoc()) << Attr.getName()
2732883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall        << ExpectedFunctionOrMethod;
2733b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
2734b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
2735bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2736c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
2737c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
273887c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2739c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
2740c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
2741c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
2742c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
2743c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
2744c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2745c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2746c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2747c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
2748c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
2749c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
2750c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2751c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2752c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2753c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2754c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
275587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
275687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(Attr.getLoc())
275787c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
2758bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
27595dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
2760bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
276187c44604325578b8de07d768391c1c9432404f5aChandler Carruth  switch (Attr.getKind()) {
2762b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
2763b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
2764b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2765c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
276687c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getLoc(),
2767c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
2768c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
276931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
277087c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(),
2771f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
277231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
277331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
277487c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(),
2775f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
277631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
2777b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
277887c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(),
2779f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2780b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2781b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
278287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(),
2783f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2784b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2785b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
2786b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
2787b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
27881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
27891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                    const AttributeList &Attr) {
279087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (hasDeclarator(D)) return;
2791f85e193739c953358c865005855253af4f68a497John McCall
279287c44604325578b8de07d768391c1c9432404f5aChandler Carruth  SourceLocation L = Attr.getLoc();
279387c44604325578b8de07d768391c1c9432404f5aChandler Carruth  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
279487c44604325578b8de07d768391c1c9432404f5aChandler Carruth    << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
2795f85e193739c953358c865005855253af4f68a497John McCall}
2796f85e193739c953358c865005855253af4f68a497John McCall
27971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
27981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
279987c44604325578b8de07d768391c1c9432404f5aChandler Carruth  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
280087c44604325578b8de07d768391c1c9432404f5aChandler Carruth    SourceLocation L = Attr.getLoc();
280187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
280287c44604325578b8de07d768391c1c9432404f5aChandler Carruth      << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
2803f85e193739c953358c865005855253af4f68a497John McCall    return;
2804f85e193739c953358c865005855253af4f68a497John McCall  }
2805f85e193739c953358c865005855253af4f68a497John McCall
280687c44604325578b8de07d768391c1c9432404f5aChandler Carruth  ValueDecl *vd = cast<ValueDecl>(D);
2807f85e193739c953358c865005855253af4f68a497John McCall  QualType type = vd->getType();
2808f85e193739c953358c865005855253af4f68a497John McCall
2809f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isDependentType() &&
2810f85e193739c953358c865005855253af4f68a497John McCall      !type->isObjCLifetimeType()) {
281187c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
2812f85e193739c953358c865005855253af4f68a497John McCall      << type;
2813f85e193739c953358c865005855253af4f68a497John McCall    return;
2814f85e193739c953358c865005855253af4f68a497John McCall  }
2815f85e193739c953358c865005855253af4f68a497John McCall
2816f85e193739c953358c865005855253af4f68a497John McCall  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
2817f85e193739c953358c865005855253af4f68a497John McCall
2818f85e193739c953358c865005855253af4f68a497John McCall  // If we have no lifetime yet, check the lifetime we're presumably
2819f85e193739c953358c865005855253af4f68a497John McCall  // going to infer.
2820f85e193739c953358c865005855253af4f68a497John McCall  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
2821f85e193739c953358c865005855253af4f68a497John McCall    lifetime = type->getObjCARCImplicitLifetime();
2822f85e193739c953358c865005855253af4f68a497John McCall
2823f85e193739c953358c865005855253af4f68a497John McCall  switch (lifetime) {
2824f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
2825f85e193739c953358c865005855253af4f68a497John McCall    assert(type->isDependentType() &&
2826f85e193739c953358c865005855253af4f68a497John McCall           "didn't infer lifetime for non-dependent type?");
2827f85e193739c953358c865005855253af4f68a497John McCall    break;
2828f85e193739c953358c865005855253af4f68a497John McCall
2829f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:   // meaningful
2830f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong: // meaningful
2831f85e193739c953358c865005855253af4f68a497John McCall    break;
2832f85e193739c953358c865005855253af4f68a497John McCall
2833f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
2834f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
283587c44604325578b8de07d768391c1c9432404f5aChandler Carruth    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
2836f85e193739c953358c865005855253af4f68a497John McCall      << (lifetime == Qualifiers::OCL_Autoreleasing);
2837f85e193739c953358c865005855253af4f68a497John McCall    break;
2838f85e193739c953358c865005855253af4f68a497John McCall  }
2839f85e193739c953358c865005855253af4f68a497John McCall
284087c44604325578b8de07d768391c1c9432404f5aChandler Carruth  D->addAttr(::new (S.Context)
284187c44604325578b8de07d768391c1c9432404f5aChandler Carruth                 ObjCPreciseLifetimeAttr(Attr.getLoc(), S.Context));
2842f85e193739c953358c865005855253af4f68a497John McCall}
2843f85e193739c953358c865005855253af4f68a497John McCall
2844f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2845f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
284611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
284711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
284811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
284911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
285011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
285111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
285211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
285311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
28541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
285511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
285611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
285711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    if (Attr.getNumArgs() != 1) {
285811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
285911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
286011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    }
286111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
286211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2863d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (Str == 0 || Str->isWide()) {
2864d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2865d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
2866d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2867d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2868d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2869d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    llvm::StringRef StrRef = Str->getString();
2870d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2871d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
2872d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
2873d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2874d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
2875d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
2876d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2877d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2878d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2879d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
2880d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2881d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2882d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2883d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2884d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
2885d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
2886f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    llvm::StringRef::iterator I = StrRef.begin();
2887f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
2888f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
2889f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
2890f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
2891d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
2892d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
2893d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2894d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
2895d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
2896d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
2897d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2898d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
2899d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
2900d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
2901d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
290211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
290387c44604325578b8de07d768391c1c9432404f5aChandler Carruth    D->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
290411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
2905d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
290611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
2907f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
2908f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
2909b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
29100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
29110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
29120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
29131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
29141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                          const AttributeList &Attr) {
291560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
29161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_device:      handleDeviceAttr      (S, D, Attr); break;
29171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_host:        handleHostAttr        (S, D, Attr); break;
29181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
291960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
292060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
292160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
292260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
2923e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
29241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
29251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                       const AttributeList &Attr) {
2926803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
29271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break;
29281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break;
2929857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
29301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleIBOutletCollection(S, D, Attr); break;
2931803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
2932207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  case AttributeList::AT_opencl_image_access:
2933ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
29346e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
29354211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
29364211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
2937bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
2938bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
2939803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
294060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
294160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
294260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
294360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
294460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
294560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
29461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_alias:       handleAliasAttr       (S, D, Attr); break;
29471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_aligned:     handleAlignedAttr     (S, D, Attr); break;
2948bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
29491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAlwaysInlineAttr  (S, D, Attr); break;
2950b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
29511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
29521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_annotate:    handleAnnotateAttr    (S, D, Attr); break;
29531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
2954bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
29551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                      handleDependencyAttr  (S, D, Attr); break;
29561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_common:      handleCommonAttr      (S, D, Attr); break;
29571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constant:    handleConstantAttr    (S, D, Attr); break;
29581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
29591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_deprecated:  handleDeprecatedAttr  (S, D, Attr); break;
29601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_destructor:  handleDestructorAttr  (S, D, Attr); break;
29613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
29621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleExtVectorTypeAttr(S, scope, D, Attr);
29633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
29641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format:      handleFormatAttr      (S, D, Attr); break;
29651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_format_arg:  handleFormatArgAttr   (S, D, Attr); break;
29661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_global:      handleGlobalAttr      (S, D, Attr); break;
29671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_gnu_inline:  handleGNUInlineAttr   (S, D, Attr); break;
29687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
29691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleLaunchBoundsAttr(S, D, Attr);
29707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
29711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_mode:        handleModeAttr        (S, D, Attr); break;
29721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_malloc:      handleMallocAttr      (S, D, Attr); break;
29731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_may_alias:   handleMayAliasAttr    (S, D, Attr); break;
29741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nocommon:    handleNoCommonAttr    (S, D, Attr); break;
29751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nonnull:     handleNonNullAttr     (S, D, Attr); break;
2976dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
2977dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
2978dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
29791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleOwnershipAttr     (S, D, Attr); break;
29801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_naked:       handleNakedAttr       (S, D, Attr); break;
29811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noreturn:    handleNoReturnAttr    (S, D, Attr); break;
29821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nothrow:     handleNothrowAttr     (S, D, Attr); break;
29831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_shared:      handleSharedAttr      (S, D, Attr); break;
29841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_vecreturn:   handleVecReturnAttr   (S, D, Attr); break;
2985b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2986b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributeList::AT_objc_ownership:
29871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCOwnershipAttr(S, D, Attr); break;
2988f85e193739c953358c865005855253af4f68a497John McCall  case AttributeList::AT_objc_precise_lifetime:
29891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
2990f85e193739c953358c865005855253af4f68a497John McCall
2991b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
2992c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
29931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_ns_consumed: handleNSConsumedAttr  (S, D, Attr); break;
2994c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
29951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSConsumesSelfAttr(S, D, Attr); break;
2996c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2997c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
299831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
299931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
3000b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
3001b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
30021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNSReturnsRetainedAttr(S, D, Attr); break;
3003b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
30046f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
30051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleReqdWorkGroupSize(S, D, Attr); break;
30066f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
3007521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
30081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth      handleInitPriorityAttr(S, D, Attr); break;
3009521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
30101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break;
30111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break;
30121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;
30131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
30141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;
30151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_used:        handleUsedAttr        (S, D, Attr); break;
30161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_visibility:  handleVisibilityAttr  (S, D, Attr); break;
30171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3018026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
30191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak:        handleWeakAttr        (S, D, Attr); break;
30201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weakref:     handleWeakRefAttr     (S, D, Attr); break;
30211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_weak_import: handleWeakImportAttr  (S, D, Attr); break;
3022803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
30231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleTransparentUnionAttr(S, D, Attr);
3024803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
30250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
30261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCExceptionAttr(S, D, Attr);
30270db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
3028d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  case AttributeList::AT_objc_method_family:
30291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleObjCMethodFamilyAttr(S, D, Attr);
3030d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    break;
30311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break;
30321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;
30331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;
30341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break;
30351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_pure:        handlePureAttr        (S, D, Attr); break;
30361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_cleanup:     handleCleanupAttr     (S, D, Attr); break;
30371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_nodebug:     handleNoDebugAttr     (S, D, Attr); break;
30381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_noinline:    handleNoInlineAttr    (S, D, Attr); break;
30391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth  case AttributeList::AT_regparm:     handleRegparmAttr     (S, D, Attr); break;
3040bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
304105f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
304205f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
30437255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
30441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleNoInstrumentFunctionAttr(S, D, Attr);
30457255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
304604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
304704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
304804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
3049f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
305052fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
3051414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributeList::AT_pcs:
30521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleCallConvAttr(S, D, Attr);
305304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
3054f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
30551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleOpenCLKernelAttr(S, D, Attr);
3056f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
305711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
30581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    handleUuidAttr(S, D, Attr);
305911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
3060803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
306182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
306282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
306382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
30647d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
30657d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
3066803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
3067803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3068803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3069803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
307060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
307160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
307260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
307360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
30741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
30751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth                                 const AttributeList &Attr,
307660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
307760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
307860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
307960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
308060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
308160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
308260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
308360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
308460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
30851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessNonInheritableDeclAttr(S, scope, D, Attr);
308660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
308760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
30881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessInheritableDeclAttr(S, scope, D, Attr);
308960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
309060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
3091803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3092803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
3093f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
309460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
309560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
309611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
30971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth    ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
309811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
309911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
310011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
310111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
310211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
310360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
310411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3105dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
310611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
3107803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
3108803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
3109803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
3110e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
3111e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
31121eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
31137b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3114e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
3115e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3116e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3117ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                FD->getInnerLocStart(),
3118e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
3119a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
3120b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
3121b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
3122c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewFD->setQualifierInfo(FD->getQualifierLoc());
3123b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3124e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3125e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3126ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                           VD->getInnerLocStart(), VD->getLocation(), II,
3127a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
312816573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
312916573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
3130b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
3131b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
3132c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      NewVD->setQualifierInfo(VD->getQualifierLoc());
3133b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
3134e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3135e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
3136e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3137e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
3138e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3139e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
31407b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3141c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
3142c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
3143c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3144c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
3145c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
3146cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3147cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
3148cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3149c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
3150c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3151c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
3152c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
3153c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
3154c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
3155c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
3156c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
3157cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3158e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3159e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
3160e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
31610744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
31620744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
31630744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
316460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
316560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
3166d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
3167d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
316860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && !WeakUndeclaredIdentifiers.empty()) {
3169d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall    if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
3170d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall      if (IdentifierInfo *Id = ND->getIdentifier()) {
3171d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
3172d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          = WeakUndeclaredIdentifiers.find(Id);
3173d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
3174d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakInfo W = I->second;
3175d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          DeclApplyPragmaWeak(S, ND, W);
3176d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakUndeclaredIdentifiers[Id] = W;
3177d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
3178e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
3179e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
3180e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
3181e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
31820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
31837f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
318460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3185bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
31860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
31870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
31880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
31890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
31900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
31910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
319260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3193bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
31940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
31950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
319660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
31970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
319854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3199f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type?
3200f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3201f85e193739c953358c865005855253af4f68a497John McCall  // Private ivars are always okay.  Unfortunately, people don't
3202f85e193739c953358c865005855253af4f68a497John McCall  // always properly make their ivars private, even in system headers.
3203f85e193739c953358c865005855253af4f68a497John McCall  // Plus we need to make fields okay, too.
3204f85e193739c953358c865005855253af4f68a497John McCall  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl))
3205f85e193739c953358c865005855253af4f68a497John McCall    return false;
3206f85e193739c953358c865005855253af4f68a497John McCall
3207f85e193739c953358c865005855253af4f68a497John McCall  // Require it to be declared in a system header.
3208f85e193739c953358c865005855253af4f68a497John McCall  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3209f85e193739c953358c865005855253af4f68a497John McCall}
3210f85e193739c953358c865005855253af4f68a497John McCall
3211f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic.
3212f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3213f85e193739c953358c865005855253af4f68a497John McCall                                       Decl *decl) {
3214f85e193739c953358c865005855253af4f68a497John McCall  if (decl && isForbiddenTypeAllowed(S, decl)) {
3215f85e193739c953358c865005855253af4f68a497John McCall    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3216f85e193739c953358c865005855253af4f68a497John McCall                        "this system declaration uses an unsupported type"));
3217f85e193739c953358c865005855253af4f68a497John McCall    return;
3218f85e193739c953358c865005855253af4f68a497John McCall  }
3219f85e193739c953358c865005855253af4f68a497John McCall
3220f85e193739c953358c865005855253af4f68a497John McCall  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3221f85e193739c953358c865005855253af4f68a497John McCall    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3222f85e193739c953358c865005855253af4f68a497John McCall  diag.Triggered = true;
3223f85e193739c953358c865005855253af4f68a497John McCall}
3224f85e193739c953358c865005855253af4f68a497John McCall
3225eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the
3226eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type.
3227eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3228eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize <= StackCapacity);
3229eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3230eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Grow the stack if necessary.
3231eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (StackSize == StackCapacity) {
3232eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    unsigned newCapacity = 2 * StackCapacity + 2;
3233eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3234eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    const char *oldBuffer = (const char*) Stack;
3235eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3236eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    if (StackCapacity)
3237eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3238eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3239eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    delete[] oldBuffer;
3240eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3241eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    StackCapacity = newCapacity;
3242eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  }
3243eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
3244eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(StackSize < StackCapacity);
3245eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  new (&Stack[StackSize++]) DelayedDiagnostic(diag);
324654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
324754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3248eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3249eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall                                              Decl *decl) {
3250eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DelayedDiagnostics &DD = S.DelayedDiagnostics;
325154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3252eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Check the invariants.
3253eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.StackSize >= state.SavedStackSize);
3254eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(state.SavedStackSize >= DD.ActiveStackBase);
3255eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  assert(DD.ParsingDepth > 0);
325654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3257eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Drop the parsing depth.
3258eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.ParsingDepth--;
325954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3260eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If there are no active diagnostics, we're done.
3261eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DD.StackSize == DD.ActiveStackBase)
3262eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    return;
326358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
32642f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
32652f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
3266a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis  if (decl && !decl->isInvalidDecl()) {
3267eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // We emit all the active diagnostics, not just those starting
3268eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    // from the saved state.  The idea is this:  we get one push for a
32692f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
32702f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
32712f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
32722f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
32732f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
3274eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3275eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      DelayedDiagnostic &diag = DD.Stack[i];
3276eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      if (diag.Triggered)
32772f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
32782f514480c448708ec382a684cf5e035d3a827ec8John McCall
3279eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall      switch (diag.Kind) {
32802f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
3281eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedDeprecationCheck(diag, decl);
32822f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
32832f514480c448708ec382a684cf5e035d3a827ec8John McCall
32842f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
3285eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall        S.HandleDelayedAccessCheck(diag, decl);
32862f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
3287f85e193739c953358c865005855253af4f68a497John McCall
3288f85e193739c953358c865005855253af4f68a497John McCall      case DelayedDiagnostic::ForbiddenType:
3289f85e193739c953358c865005855253af4f68a497John McCall        handleDelayedForbiddenType(S, diag, decl);
3290f85e193739c953358c865005855253af4f68a497John McCall        break;
329154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
329254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
329354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
329454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
329558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
3296eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
329729233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor    DD.Stack[i].Destroy();
329858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
3299eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  DD.StackSize = state.SavedStackSize;
33002f514480c448708ec382a684cf5e035d3a827ec8John McCall}
33012f514480c448708ec382a684cf5e035d3a827ec8John McCall
33022f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
33032f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
33040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (D->isDeprecated())
33052f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
33062f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
33072f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
33082f514480c448708ec382a684cf5e035d3a827ec8John McCall}
33092f514480c448708ec382a684cf5e035d3a827ec8John McCall
33109c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
33112f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
33122f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
33132f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
33142f514480c448708ec382a684cf5e035d3a827ec8John McCall
33152f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
3316ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
3317c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
3318ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
3319ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
3320c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
3321c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
3322ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
332354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
332454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3325ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramervoid Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
33268e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
332789ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                                  const ObjCInterfaceDecl *UnknownObjCClass) {
332854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
3329eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3330eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
333154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
333254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
333354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
333454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
333554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
333654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
3337ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
3338c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3339c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
33408e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
3341743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
33428e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
334389ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    else {
33448e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
334589ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
334689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian    }
33478e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
334854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
3349