SemaDeclAttr.cpp revision f315fa81eef1977b3457fd7a7d4639e060fe7278
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//                     The LLVM Compiler Infrastructure
46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source
66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details.
76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//  This file implements decl-related attribute processing.
116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h"
1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h"
166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h"
17384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h"
18acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
20fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2119510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
229c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
23797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
28e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
29e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
30e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
31a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d,
32a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
34a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  if (const ValueDecl *decl = dyn_cast<ValueDecl>(d))
356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
36a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
38a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
42bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
446217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
45755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
466217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
47d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
48183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
54d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function
55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) {
57a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  return getFunctionType(d, false) != NULL;
58a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
59a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
60a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
61d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
62d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
63a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) {
64a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  return isFunction(d)|| isa<ObjCMethodDecl>(d);
65d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
663568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
67620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
68620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
69620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
70a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) {
71620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (isFunctionOrMethod(d))
72620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
73620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
74620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
75620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
76620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
77620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
78d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  return isa<BlockDecl>(d);
79620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
80620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
81711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have
82711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator.
83711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic bool hasDeclarator(const Decl *d) {
84711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
85711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return isa<DeclaratorDecl>(d) || isa<BlockDecl>(d) || isa<TypedefDecl>(d);
86711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
87711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
88d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
91a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) {
92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
9372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
95d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d));
96d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
97d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
983568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
993568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
100d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
101d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
102d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
103a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) {
10489951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
10572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
106d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
107d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
10889951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_size();
1093568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1103568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
111a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) {
11289951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
11372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
114d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
115d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
116bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11789951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
1183568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1193568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
120a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) {
1215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
1225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
1235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  return cast<ObjCMethodDecl>(d)->getResultType();
1245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
126a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) {
127d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
12872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1293568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
130d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
131db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek    return BD->isVariadic();
132d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
1333568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->isVariadic();
1343568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1353568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1363568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
13707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruthstatic bool isInstanceMethod(const Decl *d) {
13807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(d))
13907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    return MethodDecl->isInstance();
14007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  return false;
14107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth}
14207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
144183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
145b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
147bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
148506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
149506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  if (!Cls)
1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
152506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall  IdentifierInfo* ClsName = Cls->getIdentifier();
153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
159085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1606217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
161085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
162085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
163085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1646217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
165085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
166085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
168085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
169465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara  if (RD->getTagKind() != TTK_Struct)
170085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
171085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
172085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
173085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
174085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
175e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
176e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
177e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
178e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
1793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
1803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
1813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
1823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
183bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
1849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor                                    const AttributeList &Attr, Sema &S) {
185545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
186545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
187803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
188545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
1896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
1929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
197f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    CXXScopeSpec SS;
198f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    UnqualifiedId id;
199f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
200f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall    sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>();
2019cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
2029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
2039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    if (Attr.getNumArgs() != 1) {
2049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
2069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    }
2077a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    sizeExpr = Attr.getArg(0);
2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2099cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
2109cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
2119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
2129ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
2139cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
214ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve the old source info.
215a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
216bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2179cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
2189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
222803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
224545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
228bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
230cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
235803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
236fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
23708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
239cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
2406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
24596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
24696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
2473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
24896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
24996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBAction attributes only apply to instance methods.
25263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
25363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    if (MD->isInstanceMethod()) {
254cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
25563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek      return;
25663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    }
25763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
2584ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
25963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek}
26063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
26163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
26263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // check the attribute arguments.
26363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  if (Attr.getNumArgs() > 0) {
26463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
26563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
26663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  }
26763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
26863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  // The IBOutlet attributes only apply to instance variables of
269efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  // Objective-C classes.
270efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
271cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
27263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek    return;
273efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek  }
27463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek
2754ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
27696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
27796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
278857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
279857e918a8a40deb128840308a318bf623d68295fTed Kremenek                                     Sema &S) {
280857e918a8a40deb128840308a318bf623d68295fTed Kremenek
281857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The iboutletcollection attribute can have zero or one arguments.
282a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
283857e918a8a40deb128840308a318bf623d68295fTed Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
284857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
285857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
286857e918a8a40deb128840308a318bf623d68295fTed Kremenek
287857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // The IBOutletCollection attributes only apply to instance variables of
288857e918a8a40deb128840308a318bf623d68295fTed Kremenek  // Objective-C classes.
289857e918a8a40deb128840308a318bf623d68295fTed Kremenek  if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) {
2904ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
291857e918a8a40deb128840308a318bf623d68295fTed Kremenek    return;
292857e918a8a40deb128840308a318bf623d68295fTed Kremenek  }
2933a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian  if (const ValueDecl *VD = dyn_cast<ValueDecl>(d))
2943a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
2953a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
2963a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << VD->getType() << 0;
2973a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
2983a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
2993a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
3003a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
3013a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
3023a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian        << PD->getType() << 1;
3033a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian      return;
3043a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian    }
3053a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
306a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  IdentifierInfo *II = Attr.getParameterName();
307a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!II)
308a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    II = &S.Context.Idents.get("id");
3093a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian
310b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
311a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian                        S.getScopeForContext(d->getDeclContext()->getParent()));
312a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!TypeRep) {
313a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
314a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
315a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
316b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  QualType QT = TypeRep.get();
317a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // Diagnose use of non-object type in iboutletcollection attribute.
318a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // FIXME. Gnu attribute extension ignores use of builtin types in
319a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // attributes. So, __attribute__((iboutletcollection(char))) will be
320a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  // treated as __attribute__((iboutletcollection())).
321a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
322a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian      !QT->isObjCObjectType()) {
323a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
324a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian    return;
325a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian  }
326cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
327cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                      QT));
328857e918a8a40deb128840308a318bf623d68295fTed Kremenek}
329857e918a8a40deb128840308a318bf623d68295fTed Kremenek
330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
332bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
333d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
334fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3355dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
338bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
33907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
34007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
34107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
34207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
344eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
345eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
346bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
348eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
349bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
3527a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Ex = *I;
353eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
354ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (Ex->isTypeDependent() || Ex->isValueDependent() ||
355ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
356fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
358eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
359eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
360bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
361eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
362bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
363eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
364fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
36530bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
366eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
367eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
368bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
369465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
37007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
37107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
37207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(Attr.getLoc(),
37307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth               diag::err_attribute_invalid_implicit_this_argument)
37407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "nonnull" << Ex->getSourceRange();
37507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
37607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
37707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
37807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
379eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
380eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
381de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor    QualType T = getFunctionOrMethodArgType(d, x).getNonReferenceType();
382dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
383eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
384c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
385fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
3867fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
387eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
388bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
389eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
390eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
391bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
392bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
393bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
3947fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
39546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
396de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor      QualType T = getFunctionOrMethodArgType(d, I).getNonReferenceType();
397dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
398d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
399ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian      else if (const RecordType *UT = T->getAsUnionType()) {
400ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian        if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
401ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian          RecordDecl *UD = UT->getDecl();
402ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian          for (RecordDecl::field_iterator it = UD->field_begin(),
403ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian               itend = UD->field_end(); it != itend; ++it) {
404ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian            T = it->getType();
405ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian            if (T->isAnyPointerType() || T->isBlockPointerType()) {
406ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian              NonNullArgs.push_back(I);
407ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian              break;
408ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian            }
409ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian          }
410ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian        }
411ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian      }
41246bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
413bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
414ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek    // No pointer arguments?
41560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    if (NonNullArgs.empty()) {
41660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // Warn the trivial case only if attribute is not coming from a
41760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      // macro instantiation.
41860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian      if (Attr.getLoc().isFileID())
41960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
4207fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
42160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian    }
422eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
4237fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
4247fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
4257fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
426dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
427cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
428cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                           size));
429eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
430eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
431dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekstatic void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
432dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // This attribute must be applied to a function declaration.
433dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The first argument to the attribute must be a string,
434dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // the name of the resource, for example "malloc".
435dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The following arguments must be argument indexes, the arguments must be
436dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // of integer type for Returns, otherwise of pointer type.
437dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // The difference between Holds and Takes is that a pointer may still be used
4382a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // after being held.  free() should be __attribute((ownership_takes)), whereas
4392a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  // a list append function may well be __attribute((ownership_holds)).
440dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
441dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!AL.getParameterName()) {
442dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
443dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << AL.getName()->getName() << 1;
444dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
445dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
446dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Figure out our Kind, and check arguments while we're at it.
447cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  OwnershipAttr::OwnershipKind K;
4482a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  switch (AL.getKind()) {
4492a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_takes:
450cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Takes;
451dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
452dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
453dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
454dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_holds:
457cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Holds;
458dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() < 1) {
459dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
460dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
461dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4622a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4632a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  case AttributeList::AT_ownership_returns:
464cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    K = OwnershipAttr::Returns;
465dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (AL.getNumArgs() > 1) {
466dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
467dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getNumArgs() + 1;
468dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      return;
469dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
4702a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    break;
4712a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  default:
4722a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    // This should never happen given how we are called.
4732a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    llvm_unreachable("Unknown ownership attribute");
474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
475dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
476dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (!isFunction(d) || !hasFunctionProto(d)) {
477dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName()
478dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        << 0 /*function*/;
479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    return;
480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
48207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
48307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
48407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
48507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
486dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
487dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::StringRef Module = AL.getParameterName()->getName();
488dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
489dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  // Normalize the argument, __foo__ becomes foo.
490dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  if (Module.startswith("__") && Module.endswith("__"))
491dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    Module = Module.substr(2, Module.size() - 4);
492dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
493dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::SmallVector<unsigned, 10> OwnershipArgs;
494dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
4952a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
4962a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose       ++I) {
497dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
4987a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *IdxExpr = *I;
499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    llvm::APSInt ArgNum(32);
500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
501dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
502dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
503dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << IdxExpr->getSourceRange();
504dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
505dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
506dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
508dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
509dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    if (x > NumArgs || x < 1) {
510dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
511dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
512dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      continue;
513dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
514dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    --x;
51507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (HasImplicitThisParam) {
51607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      if (x == 0) {
51707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
51807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth          << "ownership" << IdxExpr->getSourceRange();
51907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        return;
52007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      }
52107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      --x;
52207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
52307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
524dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    switch (K) {
525cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Takes:
526cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Holds: {
527dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      // Is the function argument a pointer type?
528dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      QualType T = getFunctionOrMethodArgType(d, x);
529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
530dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        // FIXME: Should also highlight argument in decl.
531dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        S.Diag(AL.getLoc(), diag::err_ownership_type)
532cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
533dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << "pointer"
534dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            << IdxExpr->getSourceRange();
535dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        continue;
536dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
537dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
538dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
539cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    case OwnershipAttr::Returns: {
540dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      if (AL.getNumArgs() > 1) {
541dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          // Is the function argument an integer type?
5427a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne          Expr *IdxExpr = AL.getArg(0);
543dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          llvm::APSInt ArgNum(32);
544dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
545dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
546dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            S.Diag(AL.getLoc(), diag::err_ownership_type)
547dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << "ownership_returns" << "integer"
548dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek                << IdxExpr->getSourceRange();
549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek            return;
550dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
551dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
552dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      break;
553dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
5542a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose    default:
5552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose      llvm_unreachable("Unknown ownership attribute");
556dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    } // switch
557dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
558dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    // Check we don't have a conflict with another ownership attribute.
559cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    for (specific_attr_iterator<OwnershipAttr>
560cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          i = d->specific_attr_begin<OwnershipAttr>(),
561cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          e = d->specific_attr_end<OwnershipAttr>();
562cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        i != e; ++i) {
563cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      if ((*i)->getOwnKind() != K) {
564cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
565cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt             I!=E; ++I) {
566cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt          if (x == *I) {
567cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
568cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                << AL.getName()->getName() << "ownership_*";
569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek          }
570dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek        }
571dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      }
572dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    }
573dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    OwnershipArgs.push_back(x);
574dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
575dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
576dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned* start = OwnershipArgs.data();
577dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  unsigned size = OwnershipArgs.size();
578dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  llvm::array_pod_sort(start, start + size);
579cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
580cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
581cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
582cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    return;
583dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  }
584cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
585cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
586cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                             start, size));
587dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}
588dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek
589332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of
590332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage.
591332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) {
592332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  switch (D->getLinkage()) {
593332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case NoLinkage:
594332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case InternalLinkage:
595332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
596332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
597332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // Template instantiations that go from external to unique-external
598332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // shouldn't get diagnosed.
599332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case UniqueExternalLinkage:
600332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return true;
601332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
602332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  case ExternalLinkage:
603332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return false;
604332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
605332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  llvm_unreachable("unknown linkage kind!");
60611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  return false;
60711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
60811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
60911e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
61011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Check the attribute arguments.
61111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() > 1) {
61211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
61311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
61411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
61511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
616332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
617332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
618332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall      << Attr.getName() << 2 /*variables and functions*/;
619332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    return;
620332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  }
621332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
622332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  NamedDecl *nd = cast<NamedDecl>(d);
623332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
62411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc rejects
62511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // class c {
62611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
62711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int b() __attribute__((weakref ("f3")));
62811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // };
62911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // and ignores the attributes of
63011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // void f(void) {
63111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //   static int a __attribute__((weakref ("v2")));
63211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // }
63311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // we reject them
6347a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  const DeclContext *Ctx = d->getDeclContext()->getRedeclContext();
6357a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl  if (!Ctx->isFileContext()) {
6367a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
637332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall        nd->getNameAsString();
6387a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl    return;
63911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
64011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
64111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // The GCC manual says
64211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
64311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // At present, a declaration to which `weakref' is attached can only
64411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // be `static'.
64511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
64611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // It also says
64711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
64811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Without a TARGET,
64911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // given as an argument to `weakref' or to `alias', `weakref' is
65011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // equivalent to `weak'.
65111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  //
65211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // gcc 4.4.1 will accept
65311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weakref));
65411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // as
65511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // int a7 __attribute__((weak));
65611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // This looks like a bug in gcc. We reject that for now. We should revisit
65711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // it if this behaviour is actually used.
65811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
659332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!hasEffectivelyInternalLinkage(nd)) {
660332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
66111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
66211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
66311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
66411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC rejects
66511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static ((alias ("y"), weakref)).
66611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // Should we? How to check that weakref is before or after alias?
66711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
66811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  if (Attr.getNumArgs() == 1) {
6697a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *Arg = Attr.getArg(0);
67011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Arg = Arg->IgnoreParenCasts();
67111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
67211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
67311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    if (Str == 0 || Str->isWide()) {
67411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
67511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola          << "weakref" << 1;
67611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola      return;
67711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    }
67811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // GCC will accept anything as the argument of weakref. Should we
67911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    // check for an existing decl?
680f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher    d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
681f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           Str->getString()));
68211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
68311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
684cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
68511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola}
68611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
687803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
689545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
6903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
6916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
693bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6947a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
6956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
6966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
697bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
699fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
7003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
7016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
703bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
704f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  if (S.Context.Target.getTriple().getOS() == llvm::Triple::Darwin) {
705f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
706f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola    return;
707f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola  }
708f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola
7096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
710bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
711f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
712f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                         Str->getString()));
7136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
715dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbarstatic void HandleNakedAttr(Decl *d, const AttributeList &Attr,
716dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar                                   Sema &S) {
717dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
718dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  if (Attr.getNumArgs() != 0) {
719dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
720dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
721dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
722dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
723dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  if (!isa<FunctionDecl>(d)) {
724dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
725dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar      << Attr.getName() << 0 /*function*/;
726dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar    return;
727dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  }
728dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
729dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
730dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar}
731dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar
732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
733af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
734dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
735af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
7363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
737af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
738af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
7395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
740c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
7415bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
742dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar      << Attr.getName() << 0 /*function*/;
7435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
7445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
745bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
746cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
747af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
748af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
74976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
750dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  // Check the attribute arguments.
75176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  if (Attr.getNumArgs() != 0) {
75276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
75376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
75476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
7551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7562cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
7571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
7582cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
759cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt      d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
7602cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
7612cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
762fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
763fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
7642cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
76576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
76676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
76734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohmanstatic void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
76834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  // check the attribute arguments.
76934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  if (Attr.getNumArgs() != 0) {
77034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
77134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman    return;
77234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  }
77334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
77434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
77534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman}
77634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman
777a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
778a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
779722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  if (isa<VarDecl>(d))
780722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
781722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
782722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
783722109c1b7718d3e8aab075ce65007b372822199Eric Christopher      << Attr.getName() << 12 /* variable */;
784a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
785a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
786a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
787a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  assert(Attr.isInvalid() == false);
788722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  if (isa<VarDecl>(d))
789722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
790722109c1b7718d3e8aab075ce65007b372822199Eric Christopher  else
791722109c1b7718d3e8aab075ce65007b372822199Eric Christopher    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
792722109c1b7718d3e8aab075ce65007b372822199Eric Christopher      << Attr.getName() << 12 /* variable */;
793a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher}
794a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher
795711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleNoReturnAttr(Decl *d, const AttributeList &attr, Sema &S) {
796711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (hasDeclarator(d)) return;
797711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
798711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckNoReturnAttr(attr)) return;
799711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
800711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (!isa<ObjCMethodDecl>(d)) {
801711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
802711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << attr.getName() << 0 /*function*/;
803711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
804711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
805711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
806711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  d->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
807711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
808711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
809711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
810711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.getNumArgs() != 0) {
811711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
812711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
813711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
814711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
815711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
816711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
817b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek}
818b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
819b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
820b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek                                       Sema &S) {
821b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
822b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
823b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  // because 'analyzer_noreturn' does not impact the type.
824b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
825545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
826e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
827b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek    return;
8286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
829b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
83019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
83119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    ValueDecl *VD = dyn_cast<ValueDecl>(d);
8323ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump    if (VD == 0 || (!VD->getType()->isBlockPointerType()
8333ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump                    && !VD->getType()->isFunctionPointerType())) {
834e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara      S.Diag(Attr.getLoc(),
835e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara             Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
836b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek             : diag::warn_attribute_wrong_decl_type)
837b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      << Attr.getName() << 0 /*function*/;
838b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek      return;
83919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
8406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
841b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek
842b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek  d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
8436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
84535cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific.
84635cc9627340b15232139b3c43fcde5973e7fad30John Thompsonstatic void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
84735cc9627340b15232139b3c43fcde5973e7fad30John Thompson                                       Sema &S) {
84835cc9627340b15232139b3c43fcde5973e7fad30John Thompson/*
84935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Returning a Vector Class in Registers
85035cc9627340b15232139b3c43fcde5973e7fad30John Thompson
851f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  According to the PPU ABI specifications, a class with a single member of
852f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  vector type is returned in memory when used as the return value of a function.
853f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  This results in inefficient code when implementing vector classes. To return
854f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  the value in a single vector register, add the vecreturn attribute to the
855f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  class definition. This attribute is also applicable to struct types.
85635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
85735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Example:
85835cc9627340b15232139b3c43fcde5973e7fad30John Thompson
85935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  struct Vector
86035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
86135cc9627340b15232139b3c43fcde5973e7fad30John Thompson    __vector float xyzw;
86235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  } __attribute__((vecreturn));
86335cc9627340b15232139b3c43fcde5973e7fad30John Thompson
86435cc9627340b15232139b3c43fcde5973e7fad30John Thompson  Vector Add(Vector lhs, Vector rhs)
86535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  {
86635cc9627340b15232139b3c43fcde5973e7fad30John Thompson    Vector result;
86735cc9627340b15232139b3c43fcde5973e7fad30John Thompson    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
86835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return result; // This will be returned in a register
86935cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
87035cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/
87101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<RecordDecl>(d)) {
87235cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
87335cc9627340b15232139b3c43fcde5973e7fad30John Thompson      << Attr.getName() << 9 /*class*/;
87435cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
87535cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
87635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
87735cc9627340b15232139b3c43fcde5973e7fad30John Thompson  if (d->getAttr<VecReturnAttr>()) {
87835cc9627340b15232139b3c43fcde5973e7fad30John Thompson    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
87935cc9627340b15232139b3c43fcde5973e7fad30John Thompson    return;
88035cc9627340b15232139b3c43fcde5973e7fad30John Thompson  }
88135cc9627340b15232139b3c43fcde5973e7fad30John Thompson
88201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  RecordDecl *record = cast<RecordDecl>(d);
88301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  int count = 0;
88401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
88501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!isa<CXXRecordDecl>(record)) {
88601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
88701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
88801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
88901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
89001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  if (!cast<CXXRecordDecl>(record)->isPOD()) {
89101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
89201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    return;
89301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
89401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
895f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  for (RecordDecl::field_iterator iter = record->field_begin();
896f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       iter != record->field_end(); iter++) {
89701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    if ((count == 1) || !iter->getType()->isVectorType()) {
89801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
89901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson      return;
90001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    }
90101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson    count++;
90201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson  }
90301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson
904cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
90535cc9627340b15232139b3c43fcde5973e7fad30John Thompson}
90635cc9627340b15232139b3c43fcde5973e7fad30John Thompson
907bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
908bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
909bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
91004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall      << Attr.getName() << 8 /*function, method, or parameter*/;
911bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return;
912bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
913bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Actually store the attribute on the declaration
914bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
915bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
91673798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
91773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
91873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
9193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
92073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
92173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
922bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
923aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall  if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) &&
924aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall      !isa<TypeDecl>(d)) {
925fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9265dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
92773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
92873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
929bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
930cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
93173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
93273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
933b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
934b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
935b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (Attr.getNumArgs() != 0) {
936b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
937b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
938b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
939bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
940b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
941186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
942b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
943b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
944b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
945b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  } else if (!isFunctionOrMethod(d)) {
946b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9475dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
948b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
949b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
950bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
951cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
952b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
953b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
9543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
9563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
957fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
958fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0 or 1";
9593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
960bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
9613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
9633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
9647a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
9653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
966ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
967ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
968fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
9693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
9703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
9713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
9723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
9733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
974bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
975c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
976fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9775dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
9783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
9793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
9803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
981f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
982f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                               priority));
9833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
9843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
9873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
988fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
989fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner       << "0 or 1";
9903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
991bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
9923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
9933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
9943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
9957a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
9963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
997ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
998ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
999fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
10013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
10023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
10033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
10043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
1005bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10066782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
1007fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
10085dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
10093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
10103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
10113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1012f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1013f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                              priority));
10143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
10153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
1016803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
10176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1018c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  int noArgs = Attr.getNumArgs();
1019c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  if (noArgs > 1) {
1020c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    S.Diag(Attr.getLoc(),
1021c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian           diag::err_attribute_wrong_number_arguments) << "0 or 1";
1022c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    return;
1023c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  }
1024c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  // Handle the case where deprecated attribute has a text message.
1025c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  StringLiteral *SE;
1026c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  if (noArgs == 1) {
10277a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *ArgExpr = Attr.getArg(0);
1028c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    SE = dyn_cast<StringLiteral>(ArgExpr);
1029c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    if (!SE) {
1030c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      S.Diag(ArgExpr->getLocStart(),
1031c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian             diag::err_attribute_not_string) << "deprecated";
1032c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian      return;
1033c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    }
10346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1035c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
1036c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    SE = StringLiteral::CreateEmpty(S.Context, 1);
1037bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1038c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context,
1039c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                              SE->getString()));
10406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1042bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1043bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  // check the attribute arguments.
1044c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  int noArgs = Attr.getNumArgs();
1045c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  if (noArgs > 1) {
1046f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher    S.Diag(Attr.getLoc(),
1047f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher           diag::err_attribute_wrong_number_arguments) << "0 or 1";
1048bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
1049bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
1050c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  // Handle the case where unavailable attribute has a text message.
1051c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  StringLiteral *SE;
1052c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  if (noArgs == 1) {
10537a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *ArgExpr = Attr.getArg(0);
1054c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    SE = dyn_cast<StringLiteral>(ArgExpr);
1055c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    if (!SE) {
1056c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      S.Diag(ArgExpr->getLocStart(),
1057c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian             diag::err_attribute_not_string) << "unavailable";
1058c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian      return;
1059c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    }
1060c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  }
1061c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  else
1062c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian    SE = StringLiteral::CreateEmpty(S.Context, 1);
1063c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian  d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context,
1064c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian                                               SE->getString()));
1065bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
1066bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
1067803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
10686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1069545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
10703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
10716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1073bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10747a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *Arg = Attr.getArg(0);
10756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
10766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1077bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
1079fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
10803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
10816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1083bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1084c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  llvm::StringRef TypeStr = Str->getString();
1085cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  VisibilityAttr::VisibilityType type;
1086bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1087c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  if (TypeStr == "default")
1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Default;
1089c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "hidden")
1090cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden;
1091c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "internal")
1092cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Hidden; // FIXME
1093c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer  else if (TypeStr == "protected")
1094cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    type = VisibilityAttr::Protected;
10956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
109608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
10976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1099bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1100cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
11016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
11040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner                                    Sema &S) {
11050db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
11060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
11070db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
11080db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1109bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11100db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
11110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
11120db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
11130db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
11140db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
1115bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1116cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
11170db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
11180db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
11190db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
1120fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
11212b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1122fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
1123fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
11240db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
1125fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
1126fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
11276217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1128fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1129fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
1130fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
1131fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
1132cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1133fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
1134fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
1135bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
1136f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1137f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
11382b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1139f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1140f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1141f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1142f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
1143f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1144f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
1145f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
1146f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
1147cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1148f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
1149f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
11509eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1152fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
11533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
11549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
11559eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1156bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
11583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11599eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
11609eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1161bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1162cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  BlocksAttr::BlockType type;
116392e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
11649eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
11659eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
1166fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
11673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
11689eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
11699eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
1170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1171cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
11729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
11739eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
1174770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1175770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
1176770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
1177fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1178fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0, 1 or 2";
1179770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1180bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1181bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1182770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
1183770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
11847a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(0);
1185770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1186ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1187ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1188fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
1190770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1191770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1192770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
1193bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1194770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
1195fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1196fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1197770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1198770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1199770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1200770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1201770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
1202770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
12037a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(1);
1204770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
1205ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1206ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(Idx, S.Context)) {
1207fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
12083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
1209770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1210770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1211770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
1212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1213770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
1214770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
1215770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
1216fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1217fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
1218770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1219770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
1220770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1221770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1222770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
1223183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1224897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
1225bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1226897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
1227897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1228897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
1229897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
1230bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1231897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
12323bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1233770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
1234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
1235770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
1236770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
12373bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1238770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
12392f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
12402f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (isa<BlockDecl>(d)) {
1241bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1242bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
12432f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
12442f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
12452f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
1246daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
1247bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
1248f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
12492f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
12503bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
12513bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
12522f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
12532f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
1254ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
12552f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1256ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
12572f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
12582f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
1259770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
1260fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1261ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
1262770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
1263770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
1264f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1265f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            nullPos));
1266770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
1267770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
1268026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
1269026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
1270026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
1271026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1272026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1273026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1274026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1275f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1276026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
12775dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
1278026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
1279026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1280bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1281f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1282f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1283f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 0;
1284f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes    return;
1285f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes  }
1286f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1287f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    if (MD->getResultType()->isVoidType()) {
1288f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1289f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      << Attr.getName() << 1;
1290f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      return;
1291f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    }
1292f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian
1293cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1294026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1295026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1296332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic void HandleWeakAttr(Decl *d, const AttributeList &attr, Sema &S) {
12976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1298332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (attr.getNumArgs() != 0) {
1299332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
13006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13026e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1303332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
1304332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1305332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall      << attr.getName() << 2 /*variables and functions*/;
1306f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
1307f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
1308f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
1309332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  NamedDecl *nd = cast<NamedDecl>(d);
1310332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall
1311332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  // 'weak' only applies to declarations with external linkage.
1312332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  if (hasEffectivelyInternalLinkage(nd)) {
1313332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall    S.Diag(attr.getLoc(), diag::err_attribute_weak_static);
13146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
13156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
1316bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1317332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall  nd->addAttr(::new (S.Context) WeakAttr(attr.getLoc(), S.Context));
13186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13206e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
13216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
13226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
13236e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
13246e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
1325bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
13266e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
13276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
13286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
13296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
13306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    isDef = (!VD->hasExternalStorage() || VD->getInit());
13316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
133206a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis    isDef = FD->hasBody();
1333d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian  } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
1334d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian    // We ignore weak import on properties and methods
13351c90f4dc686ab872013544664c797604a309c563Mike Stump    return;
13365f8f8571c52dbf12fdefb15d2fedbcccb212c15cFariborz Jahanian  } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) {
1337c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian    // Don't issue the warning for darwin as target; yet, ignore the attribute.
13383be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian    if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin ||
1339c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian        !isa<ObjCInterfaceDecl>(D))
1340c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
13413be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian        << Attr.getName() << 2 /*variable and function*/;
13423be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian      return;
13436e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
13446e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
13456e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // Merge should handle any subsequent violations.
13466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (isDef) {
1347bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
13486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar           diag::warn_attribute_weak_import_invalid_on_definition)
13496e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar      << "weak_import" << 2 /*variable and function*/;
13506e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
13516e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
13526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
1353cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
13546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
13556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
13566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
13576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                    Sema &S) {
13586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
13596f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  if (Attr.getNumArgs() != 3) {
13602b7baf0816a40af3fde3a3e174192a549b785a50John McCall    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
13616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
13626f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
13636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
13646f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
13656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
13667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne    Expr *E = Attr.getArg(i);
13676f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
1368ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor    if (E->isTypeDependent() || E->isValueDependent() ||
1369ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
13706f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
13716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
13726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
13736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
13746f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
13756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
1376cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1377cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                                     WGSize[0], WGSize[1],
13786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
13796f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
13806f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
1381026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
138217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
138317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
138417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
138517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
138617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
138717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
138817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
138917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
13907a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1391797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
139217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
1393797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
139417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
139517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
13961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1397797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
1398bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer  std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1399a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (!Error.empty()) {
1400a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1401a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    << Error;
1402797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1403797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
14041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1405a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  // This attribute cannot be applied to local variables.
1406a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1407a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1408a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner    return;
1409a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner  }
1410a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner
1411f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1412f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                           SE->getString()));
141317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
141417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
14156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1416803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
14176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1418545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
14193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
14206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1422bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1423cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
14246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1426232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1427232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1428232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
14293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1430232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1431232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1432bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1433cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1434232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1435232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1436232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1437232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1438232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
14393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1440232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1441232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1442bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1443cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1444232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1445232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1446f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1447bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1448f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1449f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1450f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1451bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1452f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1453f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1454f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1455f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1456bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1457f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
1458bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1459f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1460f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1461f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1462f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1463bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1464f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1465c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  // FIXME: Lookup probably isn't looking in the right place
1466f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1467f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1468f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1469f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
1470f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1471f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1472f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1473f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1474bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1475f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1476f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
1477f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1478f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_arg_not_function)
1479f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1480f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1481f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1482f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1483f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
1484f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
1485f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis           diag::err_attribute_cleanup_func_must_take_one_arg)
1486f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis      << Attr.getParameterName();
1487f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1488f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
149089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
149189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
149289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
149389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1494b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
1495b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor                                   ParamTy, Ty) != Sema::Compatible) {
1496f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis    S.Diag(Attr.getParameterLoc(),
149789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
149889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
149989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
150089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1501bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1502cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1503223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1504f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1505f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1506bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1507bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1508bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
15095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Attr.getNumArgs() != 1) {
15105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
15115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
15125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
15135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
15145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
15155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << Attr.getName() << 0 /*function*/;
15165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
15175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
151807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
151907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
152007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
152107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
152207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
15235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
152407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
15255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
15267a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
15275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
1528ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1529ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
15305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
15315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
15325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
15335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1534bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
15365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
15375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
15385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
15395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1540bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1542bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
154307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  if (HasImplicitThisParam) {
154407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    if (ArgIdx == 0) {
154507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
154607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << "format_arg" << IdxExpr->getSourceRange();
154707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      return;
154807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    }
154907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth    ArgIdx--;
155007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  }
155107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth
15525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
15535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1554bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
15555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
15565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
15575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
15585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
15596217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
15605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
15615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1562bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
15635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
15645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1565bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
15665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Ty = getFunctionOrMethodResultType(d);
15675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
15685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
15695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
15706217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
15715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
15725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1573bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
15745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
15755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1576bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1577bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
157807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
157907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth                                             Idx.getZExtValue()));
15805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
15815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
15822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
15832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
15842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
15852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
15862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
15873c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  IgnoredFormat,
15882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
15892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
15902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
15912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
15922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
15932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
15942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
15952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
15962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
15972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
15982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
15992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
16002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
16012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
16022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
16032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
16042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
16052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
16062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "zcmn_err")
16072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
16082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1609bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands  if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1610bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands      Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
16113c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return IgnoredFormat;
16123c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
16132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
16142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
16152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1616521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on
1617521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
1618521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
1619521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian                                   Sema &S) {
1620521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (!S.getLangOptions().CPlusPlus) {
1621521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1622521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1623521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1624521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1625b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) {
1626b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1627b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1628b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1629b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1630b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  QualType T = dyn_cast<VarDecl>(d)->getType();
1631b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (S.Context.getAsArrayType(T))
1632b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    T = S.Context.getBaseElementType(T);
1633b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  if (!T->getAs<RecordType>()) {
1634b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1635b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    Attr.setInvalid();
1636b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian    return;
1637b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian  }
1638b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1639521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (Attr.getNumArgs() != 1) {
1640521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1641521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1642521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1643521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
16447a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *priorityExpr = Attr.getArg(0);
1645b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian
1646521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  llvm::APSInt priority(32);
1647521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1648521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1649521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1650521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    << "init_priority" << priorityExpr->getSourceRange();
1651521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1652521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1653521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
16549f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian  unsigned prioritynum = priority.getZExtValue();
1655521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  if (prioritynum < 101 || prioritynum > 65535) {
1656521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1657521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    <<  priorityExpr->getSourceRange();
1658521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    Attr.setInvalid();
1659521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian    return;
1660521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  }
1661f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
1662f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                prioritynum));
1663521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian}
1664521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
1665bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1666bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1667803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
16686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1669545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1670fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
16713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
16726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1675545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
16763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
16776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1680620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1681fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16825dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
16836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
16846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
16856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
168607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // In C++ the implicit 'this' function parameter also counts, and they are
168707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  // counted from one.
168807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  bool HasImplicitThisParam = isInstanceMethod(d);
168907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth  unsigned NumArgs  = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
16906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
16916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
169201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Format = Attr.getParameterName()->getName();
16936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
16946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
16952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
16962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
16972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
16982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
16992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
17003c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
17013c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner  if (Kind == IgnoredFormat)
17023c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner    return;
17033c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner
17042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1705fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
170601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar      << "format" << Attr.getParameterName()->getName();
17076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
17117a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *IdxExpr = Attr.getArg(0);
1712803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1713ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1714ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1715fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
17163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
17176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1721fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
17223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
17236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
17276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1728bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17294a2614e94672c47395abcde60518776fbebec589Sebastian Redl  if (HasImplicitThisParam) {
17304a2614e94672c47395abcde60518776fbebec589Sebastian Redl    if (ArgIdx == 0) {
173107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth      S.Diag(Attr.getLoc(),
173207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth             diag::err_format_attribute_implicit_this_format_string)
173307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth        << IdxExpr->getSourceRange();
17344a2614e94672c47395abcde60518776fbebec589Sebastian Redl      return;
17354a2614e94672c47395abcde60518776fbebec589Sebastian Redl    }
17364a2614e94672c47395abcde60518776fbebec589Sebastian Redl    ArgIdx--;
17374a2614e94672c47395abcde60518776fbebec589Sebastian Redl  }
17381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
17403568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
17416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17422b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1743085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1744fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1745fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1746085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1747085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
17482b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1749390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1750390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1751803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1752390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1753fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1754fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
17556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1756bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
17576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
17586217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1759390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1760fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1761fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
17626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
17667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *FirstArgExpr = Attr.getArg(1);
1767803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1768ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1769ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1770fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
17713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
17726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
17766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
17773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
17786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
17796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1780803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
17816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
17826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
17836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
17853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
17863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
17872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
17886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1789fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1790fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
17916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
17926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
17936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
17946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1795fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
17963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
17976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
17986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
17996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1800cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1801cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                          Idx.getZExtValue(),
18022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
18036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
18046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
18060b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
18076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1808545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
18093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
18106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
18140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
1815bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
18160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
18170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
18180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
18190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = dyn_cast<RecordDecl>(d);
18200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
18210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1822fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
18235dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 1 /*union*/;
18246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1828bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
18290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
18300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
18310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
18320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
183317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
183417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
18350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
18360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
18370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
18380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1839bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
18400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
18410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
184290cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
1843bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
184490cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor           diag::warn_transparent_union_attribute_floating)
184590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor      << FirstType->isVectorType() << FirstType;
18460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
18470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1848bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
18490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
18500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
18510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
18520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
18530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
18540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
18550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
18560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1857bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
18580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
1859bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
18600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
18610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
18620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
18640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
18650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
1866bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1867bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1868bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
18696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1870cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
18716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
18726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
18746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1875545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
18763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
18776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
18797a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  Expr *ArgExpr = Attr.getArg(0);
1880797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1881bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
18826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
18836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
18846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
1885797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
18866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1888f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
1889f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                            SE->getString()));
18906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
18916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
18924ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
18936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1894545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
18953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
18966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
18976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1898bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1899bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //FIXME: The C++0x version of this attribute has more limited applicabilty
1900bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       than GNU's, and should error out when it is used to specify a
1901bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  //       weaker alignment, rather than being silently ignored.
19026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1903545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
1904cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
19054ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    return;
19064ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  }
19074ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
19087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne  S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
19094ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth}
19104ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
19114ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
19124ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (E->isTypeDependent() || E->isValueDependent()) {
19134ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    // Save dependent expressions in the AST to be instantiated.
1914cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
19156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
19166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1917bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1918cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object?
191949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
19204ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth  if (!E->isIntegerConstantExpr(Alignment, Context)) {
19214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_argument_not_int)
19224ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << "aligned" << E->getSourceRange();
192349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
192449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
1925396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
19264ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
19274ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth      << E->getSourceRange();
1928396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
1929396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
1930396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
1931cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
1932cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt}
1933cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1934cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
1935cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Cache the number on the Attr object if non-dependent?
1936cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  // FIXME: Perform checking of type validity
1937cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
1938cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  return;
19396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1940fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1941bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive
1942bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
1943fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
1944bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
1945bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
1946bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
19470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1948fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
1949fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
1950fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1951fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
1952fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
19533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1954fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1955fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1956fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1957fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
1958fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
19590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1960fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1961fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1962210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
196301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar  llvm::StringRef Str = Attr.getParameterName()->getName();
1964fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1965fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
1966210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
1967210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
1968fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1969fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1970fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
197173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
1972210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
1973fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
197473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
197573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
197673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
197773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
197873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
197973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
198073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
198173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
198273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
198373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
198473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
198573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
198673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
198773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
198873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
198973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1990fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1991fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1992fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1993fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1994210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
19950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1996210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
19970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1998fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1999fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
2000210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
20010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
2002fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2003fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2004fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2005fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
2006fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
2007fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
2008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2009fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
2010fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
2011fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2012fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2013fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2014fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
201573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2016183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
201773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
201873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
20192ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor    if (!OldTy->isIntegralOrEnumerationType())
202073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
202173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
202273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
202373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
202473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
202573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
202673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
202773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
202873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
2029390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2030390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
2031390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2032390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
2033f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
2034f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
2035fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
2036fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
2037fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
20383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2039fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2040fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
20413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2042fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
2043fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
204473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
204573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
204673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
204773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2048fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
20490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
2050fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
20510b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
2052fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2053fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
205473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
205573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
205673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
205773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
2058fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
20590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
2060fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
20610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
2062fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2063fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
2064fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
20650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
2066fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
20670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
2068fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
20690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
2070fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
2071fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
2072fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
20730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
2074fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
2075aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2076aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongTy;
2077aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2078aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.LongLongTy;
2079fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
2080aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      if (S.Context.Target.getLongWidth() == 64)
2081aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongTy;
2082aec7caa3c40891727164167ece11d552422803d2Chandler Carruth      else
2083aec7caa3c40891727164167ece11d552422803d2Chandler Carruth        NewTy = S.Context.UnsignedLongLongTy;
2084fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
208573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
208673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
208773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2088f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
2089f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
2090f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2091f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
2092f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
2093f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    if (OldTy->isSignedIntegerType())
2094f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.Int128Ty;
2095f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson    else
2096f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson      NewTy = S.Context.UnsignedInt128Ty;
209773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
2098fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2099fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
210073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
210173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
2102fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
2103fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
2104fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
2105ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
2106ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // FIXME: preserve existing source info.
2107a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2108ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall  } else
2109fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
2110fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
21110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
21121feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2113d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
2114d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
2115d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2116d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2117d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2118e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
21195bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (!isFunctionOrMethod(d)) {
2120d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
21215dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
2122d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
2123d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
2124bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2125cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2126d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
2127d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
21281feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
21295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
21305bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
21315bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
21325bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
21335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2135c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
21365bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
21375dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
21385bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
21395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
2140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2141cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
21425bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
21435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
21447255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
21457255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner                                           Sema &S) {
21467255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  // check the attribute arguments.
21477255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (Attr.getNumArgs() != 0) {
21487255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
21497255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
21507255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
21517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
21527255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  if (!isa<FunctionDecl>(d)) {
21537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
21547255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    << Attr.getName() << 0 /*function*/;
21557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    return;
21567255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  }
21577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2158f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher  d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2159f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                        S.Context));
21607255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner}
21617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner
2162ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2163ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2164ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2165ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2166ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2167ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2168ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2169ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2170ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<VarDecl>(d)) {
2171ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2172ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne        << Attr.getName() << 12 /*variable*/;
2173ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2174ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2175ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2176ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2177ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2178ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2179ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2180ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2181ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2182ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2183ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2184ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2185ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2186ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2187ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2188ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2189ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2190ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) {
2191ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2192ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne        << Attr.getName() << 2 /*variable and function*/;
2193ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2194ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2195ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2196ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2197ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2198ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2199ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2200ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2201ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2202ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2203ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2204ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2205ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2206ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2207ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2208ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2209ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2210ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d)) {
2211ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2212ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne        << Attr.getName() << 0 /*function*/;
2213ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2214ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2215ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
22162c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    FunctionDecl *FD = cast<FunctionDecl>(d);
22172c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    if (!FD->getResultType()->isVoidType()) {
2218723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
22192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
22202c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
22212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType()
22222c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
22232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne                                          "void");
22242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      } else {
22252c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
22262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne          << FD->getType();
22272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      }
22282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne      return;
22292c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne    }
22302c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne
2231ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2232ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2233ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2234ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2235ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2236ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2237ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2238ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2239ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2240ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2241ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2242ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2243ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2244ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2245ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<FunctionDecl>(d)) {
2246ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2247ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne        << Attr.getName() << 0 /*function*/;
2248ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2249ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2250ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2251ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2252ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2253ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2254ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2255ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2256ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2257ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2258ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  if (S.LangOpts.CUDA) {
2259ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    // check the attribute arguments.
2260ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (Attr.getNumArgs() != 0) {
2261ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2262ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2263ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2264ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2265ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    if (!isa<VarDecl>(d)) {
2266ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2267ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne        << Attr.getName() << 12 /*variable*/;
2268ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne      return;
2269ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    }
2270ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2271ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2272ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  } else {
2273ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2274ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  }
2275ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne}
2276ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne
2277cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
227826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
227926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
228026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
228126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
228226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2283bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2284c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
2285c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
228626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
22875dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
228826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
228926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
2290bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
22910130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor  if (!Fn->isInlineSpecified()) {
2292cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2293c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
2294c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
2295bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2296cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
229726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
229826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
2299711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleCallConvAttr(Decl *d, const AttributeList &attr, Sema &S) {
2300711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (hasDeclarator(d)) return;
2301711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2302711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  // Diagnostic is emitted elsewhere: here we store the (valid) attr
2303e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  CallingConv CC;
2305711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckCallingConvAttr(attr, CC))
2306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2307e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2308711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (!isa<ObjCMethodDecl>(d)) {
2309711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2310711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << attr.getName() << 0 /*function*/;
2311711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2312711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2313711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2314711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2315e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_fastcall:
2316711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) FastCallAttr(attr.getLoc(), S.Context));
2317e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2318e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_stdcall:
2319711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) StdCallAttr(attr.getLoc(), S.Context));
2320e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2321f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
2322711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) ThisCallAttr(attr.getLoc(), S.Context));
232304633eb86621747bece5643f5909222e2dd6884fDouglas Gregor    return;
2324e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  case AttributeList::AT_cdecl:
2325711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) CDeclAttr(attr.getLoc(), S.Context));
2326e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
232752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2328711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    d->addAttr(::new (S.Context) PascalAttr(attr.getLoc(), S.Context));
232952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    return;
2330e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  default:
2331e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    llvm_unreachable("unexpected attribute kind");
2332e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    return;
2333e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara  }
2334e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara}
2335e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
2336f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbournestatic void HandleOpenCLKernelAttr(Decl *d, const AttributeList &Attr, Sema &S){
2337f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  assert(Attr.isInvalid() == false);
2338f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  d->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2339f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
2340f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
2341711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2342711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2343711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2344711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2345711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.getNumArgs() != 0) {
2346711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2347711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2348711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2349ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
235055d3aaf9a537888734762170823daf750ea9036dEli Friedman
2351711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  // TODO: diagnose uses of these conventions on the wrong target.
2352711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  switch (attr.getKind()) {
2353711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_cdecl: CC = CC_C; break;
2354711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2355711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2356711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2357711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2358711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  default: llvm_unreachable("unexpected attribute kind"); return true;
2359711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2360711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2361711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2362711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2363711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2364711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleRegparmAttr(Decl *d, const AttributeList &attr, Sema &S) {
2365711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (hasDeclarator(d)) return;
2366711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2367711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  unsigned numParams;
2368711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (S.CheckRegparmAttr(attr, numParams))
2369711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return;
2370711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2371711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (!isa<ObjCMethodDecl>(d)) {
2372711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2373711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << attr.getName() << 0 /*function*/;
2374ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
2375ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
237655d3aaf9a537888734762170823daf750ea9036dEli Friedman
2377711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  d->addAttr(::new (S.Context) RegparmAttr(attr.getLoc(), S.Context, numParams));
2378711c52bb20d0c69063b52a99826fb7d2835501f1John McCall}
2379711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2380711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and
2381711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value.
2382711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckRegparmAttr(const AttributeList &attr, unsigned &numParams) {
2383711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.isInvalid())
2384711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2385711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2386711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (attr.getNumArgs() != 1) {
2387711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2388711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2389711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
2390711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  }
2391711c52bb20d0c69063b52a99826fb7d2835501f1John McCall
2392711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  Expr *NumParamsExpr = attr.getArg(0);
239355d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
2394ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2395711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
2396711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_argument_not_int)
239755d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
2398711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2399711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
240055d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
240155d3aaf9a537888734762170823daf750ea9036dEli Friedman
2402711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (Context.Target.getRegParmMax() == 0) {
2403711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
240455d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
2405711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2406711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
240755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
240855d3aaf9a537888734762170823daf750ea9036dEli Friedman
2409711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  numParams = NumParams.getZExtValue();
2410711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  if (numParams > Context.Target.getRegParmMax()) {
2411711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    Diag(attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2412711c52bb20d0c69063b52a99826fb7d2835501f1John McCall      << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
2413711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    attr.setInvalid();
2414711c52bb20d0c69063b52a99826fb7d2835501f1John McCall    return true;
241555d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
241655d3aaf9a537888734762170823daf750ea9036dEli Friedman
2417711c52bb20d0c69063b52a99826fb7d2835501f1John McCall  return false;
2418ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
2419ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
24207b381985353304a7723acb05911ff91634fa1f27Peter Collingbournestatic void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){
24217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  if (S.LangOpts.CUDA) {
24227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    // check the attribute arguments.
24237b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
24247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
24257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "1 or 2";
24267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
24277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
24287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
24297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (!isFunctionOrMethod(d)) {
24307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
24317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      << Attr.getName() << 0 /*function*/;
24327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
24337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
24347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
24357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    Expr *MaxThreadsExpr = Attr.getArg(0);
24367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MaxThreads(32);
24377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (MaxThreadsExpr->isTypeDependent() ||
24387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        MaxThreadsExpr->isValueDependent() ||
24397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
24407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
24417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
24427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      return;
24437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
24447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
24457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    llvm::APSInt MinBlocks(32);
24467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    if (Attr.getNumArgs() > 1) {
24477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      Expr *MinBlocksExpr = Attr.getArg(1);
24487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      if (MinBlocksExpr->isTypeDependent() ||
24497b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          MinBlocksExpr->isValueDependent() ||
24507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
24517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
24527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne          << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
24537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne        return;
24547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne      }
24557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    }
24567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
24577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
24587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                      MaxThreads.getZExtValue(),
24597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne                                                     MinBlocks.getZExtValue()));
24607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  } else {
24617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
24627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  }
24637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne}
24647b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne
24650744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
2466b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
2467b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
2468b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2469c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
2470c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
2471c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2472c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
2473c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
2474c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2475c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2476c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSConsumedAttr(Decl *d, const AttributeList &attr, Sema &S) {
2477c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  ParmVarDecl *param = dyn_cast<ParmVarDecl>(d);
2478c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!param) {
2479c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2480c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << SourceRange(attr.getLoc()) << attr.getName() << 4 /*parameter*/;
2481c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2482c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2483c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2484c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK, cf;
2485c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (attr.getKind() == AttributeList::AT_ns_consumed) {
2486c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
2487c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2488c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  } else {
2489c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
2490c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2491c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2492c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2493c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
2494c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
2495c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << SourceRange(attr.getLoc()) << attr.getName() << cf;
2496c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2497c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2498c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2499c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (cf)
2500c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    param->addAttr(::new (S.Context) CFConsumedAttr(attr.getLoc(), S.Context));
2501c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  else
2502c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    param->addAttr(::new (S.Context) NSConsumedAttr(attr.getLoc(), S.Context));
2503c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2504c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2505c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSConsumesSelfAttr(Decl *d, const AttributeList &attr,
2506c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                     Sema &S) {
2507c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!isa<ObjCMethodDecl>(d)) {
2508c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2509c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << SourceRange(attr.getLoc()) << attr.getName() << 13 /*method*/;
2510c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    return;
2511c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2512c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2513c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  d->addAttr(::new (S.Context) NSConsumesSelfAttr(attr.getLoc(), S.Context));
2514c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall}
2515c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2516c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &attr,
2517b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek                                        Sema &S) {
2518b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2519c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  QualType returnType;
2520bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
25215dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
2522c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = MD->getResultType();
25235dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
2524c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    returnType = FD->getResultType();
25255dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
252621531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2527c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall        << SourceRange(attr.getLoc()) << attr.getName()
2528c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall        << 3 /* function or method */;
2529b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
2530b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
2531bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2532c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool typeOK;
2533c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  bool cf;
2534c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  switch (attr.getKind()) {
2535c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  default: llvm_unreachable("invalid ownership attribute"); return;
2536c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
2537c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_retained:
2538c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_not_retained:
2539c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfNSAttribute(S, returnType);
2540c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = false;
2541c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2542c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2543c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_retained:
2544c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_returns_not_retained:
2545c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    typeOK = isValidSubjectOfCFAttribute(S, returnType);
2546c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    cf = true;
2547c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    break;
2548c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  }
2549c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2550c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  if (!typeOK) {
255121531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
2552c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << SourceRange(attr.getLoc())
2553c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      << attr.getName() << isa<ObjCMethodDecl>(d) << cf;
2554bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
25555dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
2556bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2557c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  switch (attr.getKind()) {
2558b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
2559b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
2560b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2561c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    case AttributeList::AT_ns_returns_autoreleased:
2562c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(attr.getLoc(),
2563c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall                                                             S.Context));
2564c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      return;
256531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_cf_returns_not_retained:
2566c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(attr.getLoc(),
2567f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
256831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
256931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek    case AttributeList::AT_ns_returns_not_retained:
2570c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(attr.getLoc(),
2571f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                            S.Context));
257231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek      return;
2573b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
2574c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) CFReturnsRetainedAttr(attr.getLoc(),
2575f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2576b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2577b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
2578c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall      d->addAttr(::new (S.Context) NSReturnsRetainedAttr(attr.getLoc(),
2579f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher                                                         S.Context));
2580b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
2581b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
2582b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
2583b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2584f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2585f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis  return Attr.getKind() == AttributeList::AT_dllimport ||
258611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_dllexport ||
258711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet         Attr.getKind() == AttributeList::AT_uuid;
258811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet}
258911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
259011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
259111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers.
259211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===//
259311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
259411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichetstatic void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) {
259511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
259611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    // check the attribute arguments.
259711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    if (Attr.getNumArgs() != 1) {
259811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
259911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet      return;
260011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    }
260111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    Expr *Arg = Attr.getArg(0);
260211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2603d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (Str == 0 || Str->isWide()) {
2604d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2605d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        << "uuid" << 1;
2606d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2607d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2608d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2609d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    llvm::StringRef StrRef = Str->getString();
2610d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2611d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
2612d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet                   StrRef.back() == '}';
2613d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2614d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // Validate GUID length.
2615d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (IsCurly && StrRef.size() != 38) {
2616d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2617d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2618d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2619d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    if (!IsCurly && StrRef.size() != 36) {
2620d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2621d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      return;
2622d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
2623d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet
2624d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
2625d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
2626f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    llvm::StringRef::iterator I = StrRef.begin();
2627f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    if (IsCurly) // Skip the optional '{'
2628f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson       ++I;
2629f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson
2630f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson    for (int i = 0; i < 36; ++i) {
2631d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      if (i == 8 || i == 13 || i == 18 || i == 23) {
2632d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        if (*I != '-') {
2633d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2634d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet          return;
2635d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        }
2636d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      } else if (!isxdigit(*I)) {
2637d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2638d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet        return;
2639d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      }
2640d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet      I++;
2641d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet    }
264211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet
264311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    d->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
264411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet                                          Str->getString()));
2645d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet  } else
264611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
2647f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis}
2648f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis
2649b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
26500744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
26510744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
26520744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
265360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessNonInheritableDeclAttr(Scope *scope, Decl *D,
265460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                          const AttributeList &Attr, Sema &S) {
265560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  switch (Attr.getKind()) {
265660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:      HandleDeviceAttr      (D, Attr, S); break;
265760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:        HandleHostAttr        (D, Attr, S); break;
265860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
265960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  default:
266060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
266160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  }
266260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
2663e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara
266460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessInheritableDeclAttr(Scope *scope, Decl *D,
266560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                       const AttributeList &Attr, Sema &S) {
2666803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
266763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek  case AttributeList::AT_IBAction:            HandleIBAction(D, Attr, S); break;
2668857e918a8a40deb128840308a318bf623d68295fTed Kremenek    case AttributeList::AT_IBOutlet:          HandleIBOutlet(D, Attr, S); break;
2669857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case AttributeList::AT_IBOutletCollection:
2670857e918a8a40deb128840308a318bf623d68295fTed Kremenek      HandleIBOutletCollection(D, Attr, S); break;
2671803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
2672ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
26736e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson  case AttributeList::AT_vector_size:
26744211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_vector_type:
26754211bb68cff1f310be280f66a59520548ef99d8fBob Wilson  case AttributeList::AT_neon_polyvector_type:
2676bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
2677bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
2678803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
267960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_device:
268060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_host:
268160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  case AttributeList::AT_overloadable:
268260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // Ignore, this is a non-inheritable attribute, handled
268360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // by ProcessNonInheritableDeclAttr.
268460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    break;
26857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_alias:       HandleAliasAttr       (D, Attr, S); break;
26867725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_aligned:     HandleAlignedAttr     (D, Attr, S); break;
2687bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
2688af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
2689b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
2690bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
26917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_annotate:    HandleAnnotateAttr    (D, Attr, S); break;
2692bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  case AttributeList::AT_carries_dependency:
26937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt                                      HandleDependencyAttr  (D, Attr, S); break;
2694a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  case AttributeList::AT_common:      HandleCommonAttr      (D, Attr, S); break;
2695ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_constant:    HandleConstantAttr    (D, Attr, S); break;
26967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
26977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_deprecated:  HandleDeprecatedAttr  (D, Attr, S); break;
26987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_destructor:  HandleDestructorAttr  (D, Attr, S); break;
26993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
27009cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    HandleExtVectorTypeAttr(scope, D, Attr, S);
27013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
27027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format:      HandleFormatAttr      (D, Attr, S); break;
27037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_format_arg:  HandleFormatArgAttr   (D, Attr, S); break;
2704ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_global:      HandleGlobalAttr      (D, Attr, S); break;
27057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr   (D, Attr, S); break;
27067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne  case AttributeList::AT_launch_bounds:
27077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    HandleLaunchBoundsAttr(D, Attr, S);
27087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne    break;
27097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_mode:        HandleModeAttr        (D, Attr, S); break;
27107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_malloc:      HandleMallocAttr      (D, Attr, S); break;
271134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman  case AttributeList::AT_may_alias:   HandleMayAliasAttr    (D, Attr, S); break;
2712a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher  case AttributeList::AT_nocommon:    HandleNoCommonAttr    (D, Attr, S); break;
27137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nonnull:     HandleNonNullAttr     (D, Attr, S); break;
2714dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_returns:
2715dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_takes:
2716dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek  case AttributeList::AT_ownership_holds:
2717dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek      HandleOwnershipAttr     (D, Attr, S); break;
2718dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar  case AttributeList::AT_naked:       HandleNakedAttr       (D, Attr, S); break;
27197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;
27207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;
2721ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne  case AttributeList::AT_shared:      HandleSharedAttr      (D, Attr, S); break;
272235cc9627340b15232139b3c43fcde5973e7fad30John Thompson  case AttributeList::AT_vecreturn:   HandleVecReturnAttr   (D, Attr, S); break;
2723b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
2724b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
2725c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_cf_consumed:
2726c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumed: HandleNSConsumedAttr  (D, Attr, S); break;
2727c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_consumes_self:
2728c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall    HandleNSConsumesSelfAttr(D, Attr, S); break;
2729c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall
2730c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall  case AttributeList::AT_ns_returns_autoreleased:
273131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_ns_returns_not_retained:
273231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek  case AttributeList::AT_cf_returns_not_retained:
2733b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
2734b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
2735b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    HandleNSReturnsRetainedAttr(D, Attr, S); break;
2736b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
27376f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
27386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    HandleReqdWorkGroupSize(D, Attr, S); break;
27396f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
2740521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian  case AttributeList::AT_init_priority:
2741521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian      HandleInitPriorityAttr(D, Attr, S); break;
2742521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian
27437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_packed:      HandlePackedAttr      (D, Attr, S); break;
27447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_section:     HandleSectionAttr     (D, Attr, S); break;
27457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
27467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_unused:      HandleUnusedAttr      (D, Attr, S); break;
27477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_used:        HandleUsedAttr        (D, Attr, S); break;
27487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_visibility:  HandleVisibilityAttr  (D, Attr, S); break;
2749026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
2750026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
27517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak:        HandleWeakAttr        (D, Attr, S); break;
275211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  case AttributeList::AT_weakref:     HandleWeakRefAttr     (D, Attr, S); break;
27537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_weak_import: HandleWeakImportAttr  (D, Attr, S); break;
2754803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
2755803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
2756803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
27570db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
27580db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
27590db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
27607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nsobject:    HandleObjCNSObject    (D, Attr, S); break;
27617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_blocks:      HandleBlocksAttr      (D, Attr, S); break;
27627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_sentinel:    HandleSentinelAttr    (D, Attr, S); break;
27637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_const:       HandleConstAttr       (D, Attr, S); break;
27647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_pure:        HandlePureAttr        (D, Attr, S); break;
27657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_cleanup:     HandleCleanupAttr     (D, Attr, S); break;
27667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_nodebug:     HandleNoDebugAttr     (D, Attr, S); break;
27677725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_noinline:    HandleNoInlineAttr    (D, Attr, S); break;
27687725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt  case AttributeList::AT_regparm:     HandleRegparmAttr     (D, Attr, S); break;
2769bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
277005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
277105f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
27727255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
27737255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    HandleNoInstrumentFunctionAttr(D, Attr, S);
27747255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner    break;
277504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_stdcall:
277604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_cdecl:
277704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  case AttributeList::AT_fastcall:
2778f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case AttributeList::AT_thiscall:
277952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case AttributeList::AT_pascal:
2780e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara    HandleCallConvAttr(D, Attr, S);
278104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    break;
2782f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  case AttributeList::AT_opencl_kernel_function:
2783f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    HandleOpenCLKernelAttr(D, Attr, S);
2784f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    break;
278511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet  case AttributeList::AT_uuid:
278611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    HandleUuidAttr(D, Attr, S);
278711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet    break;
2788803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
278982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    // Ask target about the attribute.
279082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
279182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
27927d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth      S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
27937d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth        << Attr.getName();
2794803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
2795803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2796803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2797803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
279860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
279960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls.  If the attribute is a type attribute, just
280060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
280160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
280260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessDeclAttribute(Scope *scope, Decl *D,
280360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 const AttributeList &Attr, Sema &S,
280460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
280560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isInvalid())
280660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
280760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
280860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
280960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    // FIXME: Try to deal with other __declspec attributes!
281060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    return;
281160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
281260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (NonInheritable)
281360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessNonInheritableDeclAttr(scope, D, Attr, S);
281460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
281560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable)
281660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessInheritableDeclAttr(scope, D, Attr, S);
281760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne}
281860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne
2819803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
2820803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
2821f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
282260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    const AttributeList *AttrList,
282360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                    bool NonInheritable, bool Inheritable) {
282411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
282560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttribute(S, D, *l, *this, NonInheritable, Inheritable);
282611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  }
282711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola
282811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // GCC accepts
282911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // static int a9 __attribute__((weakref));
283011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola  // but that looks really pointless. We reject it.
283160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
283211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
2833dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek    dyn_cast<NamedDecl>(D)->getNameAsString();
283411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola    return;
2835803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
2836803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
2837803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
2838e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
2839e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
28401eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
28417b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
2842e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
2843e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
2844e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
2845e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
2846a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                FD->getType(), FD->getTypeSourceInfo());
2847b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (FD->getQualifier()) {
2848b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
2849b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange());
2850b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
2851e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
2852e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
2853e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                           VD->getLocation(), II,
2854a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                           VD->getType(), VD->getTypeSourceInfo(),
285516573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClass(),
285616573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor                           VD->getStorageClassAsWritten());
2857b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    if (VD->getQualifier()) {
2858b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      VarDecl *NewVD = cast<VarDecl>(NewD);
2859b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall      NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange());
2860b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    }
2861e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2862e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
2863e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
2864e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
2865e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
2866e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
28677b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
2868c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
2869c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
2870c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
2871c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
2872c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
2873cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
2874cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt                                            NDId->getName()));
2875cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
2876c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
2877c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
2878c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
2879c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
2880c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
2881c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
2882c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
2883c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
2884cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
2885e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2886e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
2887e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
28880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
28890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
28900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
289160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
289260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne                                 bool NonInheritable, bool Inheritable) {
2893d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // It's valid to "forward-declare" #pragma weak, in which case we
2894d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall  // have to do this.
289560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne  if (Inheritable && !WeakUndeclaredIdentifiers.empty()) {
2896d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall    if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
2897d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall      if (IdentifierInfo *Id = ND->getIdentifier()) {
2898d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
2899d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          = WeakUndeclaredIdentifiers.find(Id);
2900d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
2901d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakInfo W = I->second;
2902d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          DeclApplyPragmaWeak(S, ND, W);
2903d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall          WeakUndeclaredIdentifiers[Id] = W;
2904d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall        }
2905e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
2906e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
2907e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
2908e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
29090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
29107f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
291160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
2912bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
29130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
29140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
29150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
29160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
29170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
29180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
291960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne      ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
2920bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
29210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
29220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
292360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne    ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
29240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
292554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
292654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// PushParsingDeclaration - Enter a new "scope" of deprecation
292754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// warnings.
292854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall///
292954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// The state token we use is the start index of this scope
293054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// on the warning stack.
2931f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallSema::ParsingDeclStackState Sema::PushParsingDeclaration() {
293254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclDepth++;
29332f514480c448708ec382a684cf5e035d3a827ec8John McCall  return (ParsingDeclStackState) DelayedDiagnostics.size();
293454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
293554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
2936d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) {
293754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
293854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclDepth--;
293954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
29402f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (DelayedDiagnostics.empty())
294154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
294254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
294354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  unsigned SavedIndex = (unsigned) S;
29442f514480c448708ec382a684cf5e035d3a827ec8John McCall  assert(SavedIndex <= DelayedDiagnostics.size() &&
294554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall         "saved index is out of bounds");
294654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
294758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  unsigned E = DelayedDiagnostics.size();
294858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
29492f514480c448708ec382a684cf5e035d3a827ec8John McCall  // We only want to actually emit delayed diagnostics when we
29502f514480c448708ec382a684cf5e035d3a827ec8John McCall  // successfully parsed a decl.
29512f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (D) {
29522f514480c448708ec382a684cf5e035d3a827ec8John McCall    // We really do want to start with 0 here.  We get one push for a
29532f514480c448708ec382a684cf5e035d3a827ec8John McCall    // decl spec and another for each declarator;  in a decl group like:
29542f514480c448708ec382a684cf5e035d3a827ec8John McCall    //   deprecated_typedef foo, *bar, baz();
29552f514480c448708ec382a684cf5e035d3a827ec8John McCall    // only the declarator pops will be passed decls.  This is correct;
29562f514480c448708ec382a684cf5e035d3a827ec8John McCall    // we really do need to consider delayed diagnostics from the decl spec
29572f514480c448708ec382a684cf5e035d3a827ec8John McCall    // for each of the different declarations.
295858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    for (unsigned I = 0; I != E; ++I) {
29592f514480c448708ec382a684cf5e035d3a827ec8John McCall      if (DelayedDiagnostics[I].Triggered)
29602f514480c448708ec382a684cf5e035d3a827ec8John McCall        continue;
29612f514480c448708ec382a684cf5e035d3a827ec8John McCall
29622f514480c448708ec382a684cf5e035d3a827ec8John McCall      switch (DelayedDiagnostics[I].Kind) {
29632f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Deprecation:
29642f514480c448708ec382a684cf5e035d3a827ec8John McCall        HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D);
29652f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
29662f514480c448708ec382a684cf5e035d3a827ec8John McCall
29672f514480c448708ec382a684cf5e035d3a827ec8John McCall      case DelayedDiagnostic::Access:
29682f514480c448708ec382a684cf5e035d3a827ec8John McCall        HandleDelayedAccessCheck(DelayedDiagnostics[I], D);
29692f514480c448708ec382a684cf5e035d3a827ec8John McCall        break;
297054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall      }
297154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    }
297254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
297354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
297458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // Destroy all the delayed diagnostics we're about to pop off.
297558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  for (unsigned I = SavedIndex; I != E; ++I)
297658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    DelayedDiagnostics[I].destroy();
297758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
29782f514480c448708ec382a684cf5e035d3a827ec8John McCall  DelayedDiagnostics.set_size(SavedIndex);
29792f514480c448708ec382a684cf5e035d3a827ec8John McCall}
29802f514480c448708ec382a684cf5e035d3a827ec8John McCall
29812f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) {
29822f514480c448708ec382a684cf5e035d3a827ec8John McCall  do {
29832f514480c448708ec382a684cf5e035d3a827ec8John McCall    if (D->hasAttr<DeprecatedAttr>())
29842f514480c448708ec382a684cf5e035d3a827ec8John McCall      return true;
29852f514480c448708ec382a684cf5e035d3a827ec8John McCall  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
29862f514480c448708ec382a684cf5e035d3a827ec8John McCall  return false;
29872f514480c448708ec382a684cf5e035d3a827ec8John McCall}
29882f514480c448708ec382a684cf5e035d3a827ec8John McCall
29899c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
29902f514480c448708ec382a684cf5e035d3a827ec8John McCall                                         Decl *Ctx) {
29912f514480c448708ec382a684cf5e035d3a827ec8John McCall  if (isDeclDeprecated(Ctx))
29922f514480c448708ec382a684cf5e035d3a827ec8John McCall    return;
29932f514480c448708ec382a684cf5e035d3a827ec8John McCall
29942f514480c448708ec382a684cf5e035d3a827ec8John McCall  DD.Triggered = true;
2995ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!DD.getDeprecationMessage().empty())
2996c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated_message)
2997ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName()
2998ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationMessage();
2999c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian  else
3000c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(DD.Loc, diag::warn_deprecated)
3001ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      << DD.getDeprecationDecl()->getDeclName();
300254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
300354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3004ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramervoid Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
30058e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                  SourceLocation Loc,
3006743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne                                  bool UnknownObjCClass) {
300754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Delay if we're currently parsing a declaration.
300854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (ParsingDeclDepth) {
3009c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D,
3010c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                                                    Message));
301154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
301254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  }
301354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
301454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  // Otherwise, don't warn if our current context is deprecated.
301554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  if (isDeclDeprecated(cast<Decl>(CurContext)))
301654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return;
3017ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  if (!Message.empty())
3018c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3019c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian                                             << Message;
30208e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  else {
3021743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne    if (!UnknownObjCClass)
30228e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
30238e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian    else
30248e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
30258e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian  }
302654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall}
3027