SemaDeclAttr.cpp revision 210ae989a51dcb115b928829abd7c4c4ae0c01bd
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
146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "Sema.h"
156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h"
16acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
17acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
18fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
1912bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h"
20797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h"
216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
27a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d,
28a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek                                           bool blocksToo = true) {
296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
30a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  if (const ValueDecl *decl = dyn_cast<ValueDecl>(d))
316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
32a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
34a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
38bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
406217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<PointerType>()->getPointeeType();
41755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
426217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
43d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
44183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  return Ty->getAs<FunctionType>();
456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
473568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
483568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
493568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
50d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod - Return true if the given decl has function
51a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable).
52a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) {
53a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  return getFunctionType(d, false) != NULL;
54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek}
55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek
56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function
57d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
58d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
59a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) {
60a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek  return isFunction(d)|| isa<ObjCMethodDecl>(d);
61d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
623568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
63620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
64620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
65620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
66a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) {
67620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (isFunctionOrMethod(d))
68620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
69620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
70620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
71620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
72620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
73620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
74d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  return isa<BlockDecl>(d);
75620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
76620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
77d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
78d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
79620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) {
81620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
8272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
83620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
84d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d));
85d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
90d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
91d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
92a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) {
9389951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
9472564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
95d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
96d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getNumParams();
9789951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_size();
983568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
993568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
100a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) {
10189951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
10272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
103d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
104d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->getParamDecl(Idx)->getType();
105bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
10689951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
1073568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1083568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
109a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) {
1105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
1115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return cast<FunctionProtoType>(FnTy)->getResultType();
1125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  return cast<ObjCMethodDecl>(d)->getResultType();
1135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
1145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
115a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) {
116d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
11772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1183568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
119d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
120d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian    return BD->IsVariadic();
121d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian  else {
1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->isVariadic();
1233568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1243568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1253568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
1266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
127183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
128b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
130bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
131183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAs<ObjCInterfaceType>();
1326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!ClsT)
1336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
136bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
142085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
1436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const PointerType *PT = T->getAs<PointerType>();
144085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
145085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
146085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
1476217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
148085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
149085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
150bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
151085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
152085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (RD->getTagKind() != TagDecl::TK_struct)
153085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
154085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
155085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
156085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
157085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
158e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
159e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
160e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
161e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
1623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
1633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
1643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
1653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
1679cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor                                    const AttributeList &Attr, Sema &S) {
168545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
169545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
170803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
171545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
1759cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  Expr *sizeExpr;
1779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1789cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Special case where the argument is a template id.
1799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (Attr.getParameterName()) {
1809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    sizeExpr = S.ActOnDeclarationNameExpr(scope, Attr.getLoc(),
1819cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor                               Attr.getParameterName(),
1829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor                               false, 0, false).takeAs<Expr>();
1839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  } else {
1849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // check the attribute arguments.
1859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    if (Attr.getNumArgs() != 1) {
1869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      return;
1889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    }
1899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    sizeExpr = static_cast<Expr *>(Attr.getArg(0));
1906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor
1929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // Instantiate/Install the vector type, and let Sema build the type for us.
1939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  // This will run the reguired checks.
1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc());
1959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor  if (!T.isNull()) {
1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    tDecl->setUnderlyingType(T);
197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1989cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    // Remember this typedef decl, we will need it later for diagnostics.
1999cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    S.ExtVectorDecls.push_back(tDecl);
2006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
203065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
204bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleVectorSizeAttribute - this attribute is only applicable to integral
205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// and float scalars, although arrays, pointers, and function return values are
206bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// allowed in conjunction with this construct. Aggregates with this attribute
207bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// are invalid, even if they are of the same size as a corresponding scalar.
208bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// The raw attribute should contain precisely 1 argument, the vector size for
209bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// the variable, measured in bytes. If curType and rawAttr are well formed,
210bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// this routine will return a new vector type.
211803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
212065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  QualType CurType;
213065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
214065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = VD->getType();
215065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
216065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = TD->getUnderlyingType();
217065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else {
218fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
219fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc());
220065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
221065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  }
222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
223065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Check the attribute arugments.
224545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
2253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
226065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
228545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
230803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
231fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
232fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "vector_size" << sizeExpr->getSourceRange();
233065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
235bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // navigate to the base type - we need to provide for vector pointers, vector
236bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arrays, and functions returning vectors.
237b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (CurType->isPointerType() || CurType->isArrayType() ||
238b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner      CurType->isFunctionType()) {
2392db15bdd945163eacfa4623fd2e32a536ed2dd3bChris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType;
2402db15bdd945163eacfa4623fd2e32a536ed2dd3bChris Lattner    return;
2416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
2426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     do {
2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     if (PointerType *PT = dyn_cast<PointerType>(canonType))
2446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = PT->getPointeeType().getTypePtr();
2456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
2466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = AT->getElementType().getTypePtr();
2476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
2486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = FT->getResultType().getTypePtr();
2496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     } while (canonType->isPointerType() || canonType->isArrayType() ||
2506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType->isFunctionType());
2516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     */
2526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
25382afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner  // the base type must be integer or float, and can't already be a vector.
25482afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner  if (CurType->isVectorType() ||
25582afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner      (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
256d162584991885ab004a02573a73ce06422b921fcChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
257065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
259803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vecSize is specified in bytes - convert to bits.
261bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
262bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the vector size needs to be an integral multiple of the type size.
2646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize % typeSize) {
265fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
266fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
267065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
270fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
271fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
272065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
274bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
275065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Success! Instantiate the vector type, the number of elements is > 0, and
276065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // not required to be a power of 2, unlike GCC.
277803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
278bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
279065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
280065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    VD->setType(CurType);
281bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  else
282065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    cast<TypedefDecl>(D)->setUnderlyingType(CurType);
2836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
285803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
287545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
291bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
2926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
293a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson    TD->addAttr(::new (S.Context) PackedAttr);
2946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
298803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
299fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
30008631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
3016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
302a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson      FD->addAttr(::new (S.Context) PackedAttr);
3036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
3043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
3056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
30796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
30896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
30996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
3103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
31196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
31296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
313bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
31496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // The IBOutlet attribute only applies to instance variables of Objective-C
31596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // classes.
316327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek  if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))
31740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    d->addAttr(::new (S.Context) IBOutletAttr());
31896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  else
319327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet);
32096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
32196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
322eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
323bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
324bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // ignore it as well
325d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
326fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3275dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
330bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
331d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
333eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
334eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
335bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
338bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
339bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
340eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
341f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek    Expr *Ex = static_cast<Expr *>(*I);
342eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
344fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
345fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
346eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
348bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
349eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
352fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
35330bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
354eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
355eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
356bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
357465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
358eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
359eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
360bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    QualType T = getFunctionOrMethodArgType(d, x);
361dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
362eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
363fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
364fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
3657fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
366eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
367bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
368eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
369eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
370bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
371bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // If no arguments were specified to __attribute__((nonnull)) then all pointer
372bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // arguments have a nonnull attribute.
3737fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
37446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
37546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek      QualType T = getFunctionOrMethodArgType(d, I);
376dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek      if (T->isAnyPointerType() || T->isBlockPointerType())
377d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
37846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
379bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
3807fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    if (NonNullArgs.empty()) {
3817fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
3827fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
3837fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    }
384eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
3857fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3867fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
3877fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
3887fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  std::sort(start, start + size);
38940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) NonNullAttr(start, size));
390eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
391eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
392803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
394545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
3953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
3966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
398bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
399545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
4016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
402bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
4036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
404fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
4053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
4066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
408bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
4096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *Alias = Str->getStrData();
4106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned AliasLen = Str->getByteLength();
411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
4126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
413bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
41440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
4156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
417bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
418af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
419af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  // check the attribute arguments.
420af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
4213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
422af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
423af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
4245bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
425c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
4265bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4275dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
4285bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
4295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
430bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
43140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) AlwaysInlineAttr());
432af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
433af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
43476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
43576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  // check the attribute arguments.
43676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  if (Attr.getNumArgs() != 0) {
43776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
43876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn    return;
43976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  }
4401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4412cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType RetTy = FD->getResultType();
4432cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
4442cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      d->addAttr(::new (S.Context) MallocAttr());
4452cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek      return;
4462cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    }
447fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn  }
448fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn
4492cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
45076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn}
45176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn
452b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
4535dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek                                     Sema &S) {
4546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
455545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
4563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
457b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek    return false;
4586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
459d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
46019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
46119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    ValueDecl *VD = dyn_cast<ValueDecl>(d);
46219c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    if (VD == 0 || !VD->getType()->isBlockPointerType()) {
46319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4645dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek        << Attr.getName() << 0 /*function*/;
46519c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump      return false;
46619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
4676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
468bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
469b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  return true;
470b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek}
471b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek
472b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
473bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (HandleCommonNoReturnAttr(d, Attr, S))
47440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    d->addAttr(::new (S.Context) NoReturnAttr());
475b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek}
476b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek
477b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
478b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek                                       Sema &S) {
479bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (HandleCommonNoReturnAttr(d, Attr, S))
48040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
4816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
48373798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
48473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
48573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
4863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
48773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
48873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
490d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) {
491fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4925dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
49373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
49473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
495bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
49640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) UnusedAttr());
49773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
49873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
499b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
500b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
501b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (Attr.getNumArgs() != 0) {
502b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
503b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
504b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
505bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
506b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
507186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
508b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
509b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
510b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
511b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  } else if (!isFunctionOrMethod(d)) {
512b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
5135dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
514b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
515b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
516bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
51740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) UsedAttr());
518b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
519b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
5203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
5223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
523fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
524fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0 or 1";
5253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
526bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
5273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
5293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
5303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
5313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
5323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
533fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
5343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
5353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
5363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
5373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
5383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
539bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
540c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
541fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
5425dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
5433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
5443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
5453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
54640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) ConstructorAttr(priority));
5473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
5483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
5513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
552fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
553fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner       << "0 or 1";
5543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
555bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
5563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
5583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
5593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
5603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
5613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
562fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
5633c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
5643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
5653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
5663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
5673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
568bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
5696782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
570fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
5715dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
5723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
5733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
5743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
57540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) DestructorAttr(priority));
5763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
5773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
578803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
580545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
5813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
5826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
584bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
58540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) DeprecatedAttr());
5866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
588bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
589bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  // check the attribute arguments.
590bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
591bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
592bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
593bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
594bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
59540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) UnavailableAttr());
596bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
597bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
598803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
600545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
6013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
6026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
604bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
605545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
608bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
610fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
6113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
6126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
614bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *TypeStr = Str->getStrData();
6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned TypeLen = Str->getByteLength();
6176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  VisibilityAttr::VisibilityTypes type;
618bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::DefaultVisibility;
6216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
6226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility;
6236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
6246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility; // FIXME
6256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
6266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::ProtectedVisibility;
6276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
62808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
6296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
631bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
63240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) VisibilityAttr(type));
6336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6350db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
6360db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner                                    Sema &S) {
6370db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
6380db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
6390db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
6400db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
641bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6420db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
6430db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
6440db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
6450db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
6460db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
647bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
64840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCExceptionAttr());
6490db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
6500db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
6510db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
652fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
653fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
654fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
655fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
6560db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
657fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
658fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
6596217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
660fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
661fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
662fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
663fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
66440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
665fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
666fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
667bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void
668f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
669f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
670f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
671f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
672f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
673f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
674f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
675f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
676f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
677f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
678f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
67940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) OverloadableAttr());
680f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
681f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
6829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
683bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
684fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
6853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
6869eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
688bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6899eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
6903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
6919eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6929eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
693bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
6949eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  BlocksAttr::BlocksAttrTypes type;
69592e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
6969eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
6979eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
698fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
6993c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
7009eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
7019eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
702bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
70340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) BlocksAttr(type));
7049eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
7059eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
706770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
707770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
708770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
709fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
710fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0, 1 or 2";
711770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
712bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
713bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
714770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
715770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
716770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(0));
717770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
718770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
719fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
7203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
721770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
722770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
723770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
724bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
725770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
726fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
727fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
728770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
729770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
730770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
731770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
732770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
733770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
734770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(1));
735770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
736770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
737fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
7383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
739770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
740770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
741770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
742bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
743770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
744770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
745770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
746fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
747fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
748770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
749770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
750770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
751770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
752770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
753183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    const FunctionType *FT = FD->getType()->getAs<FunctionType>();
754897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
755bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
756897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
757897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
758897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
759897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
760bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
761897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
7623bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
763770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
764bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
765770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
766770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
7673bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
768770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
7692f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
7702f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (isa<BlockDecl>(d)) {
771bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
772bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // caller.
7732f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
7742f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
7752f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
776daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
777bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
778183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
7792f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
7803bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
7813bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
7822f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
7832f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
784ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
7852f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
786ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
7872f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
7882f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
789770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
790fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
791ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
792770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
793770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
79440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
795770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
796770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
797026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
798026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
799026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
800026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
801026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
802026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
803026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
804026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // TODO: could also be applied to methods?
805026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
806026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (!Fn) {
807026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8085dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
809026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
810026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
811bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
81240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
813026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
814026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
815026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
8166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
817545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
822f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  /* weak only applies to non-static declarations */
823f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  bool isStatic = false;
824f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
825f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    isStatic = VD->getStorageClass() == VarDecl::Static;
826f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
827f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    isStatic = FD->getStorageClass() == FunctionDecl::Static;
828f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
829f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  if (isStatic) {
830f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) <<
831f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian      dyn_cast<NamedDecl>(D)->getNameAsString();
832f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian    return;
833f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian  }
834f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian
8356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // TODO: could also be applied to methods?
8366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
8376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8385dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
8396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
8406e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
841bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
84240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakAttr());
8436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8456e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
8466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
8476e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
8486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8496e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
850bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
8516e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
8526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
8536e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
8546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
8556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    isDef = (!VD->hasExternalStorage() || VD->getInit());
8566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8576fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis    isDef = FD->getBody();
858d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian  } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
859d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian    // We ignore weak import on properties and methods
8601c90f4dc686ab872013544664c797604a309c563Mike Stump    return;
8616e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  } else {
8626e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8635dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 2 /*variable and function*/;
8646e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
8656e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
8666e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
8676e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // Merge should handle any subsequent violations.
8686e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (isDef) {
869bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
8706e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar           diag::warn_attribute_weak_import_invalid_on_definition)
8716e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar      << "weak_import" << 2 /*variable and function*/;
8726e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
8736e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
8746e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
87540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) WeakImportAttr());
8766e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
8776e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
878026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
8796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
880545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8847b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8852f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Attribute can be applied only to functions or variables.
886026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (isa<VarDecl>(D)) {
88740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    D->addAttr(::new (S.Context) DLLImportAttr());
8882f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8892f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8902f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
891026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
8922f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (!FD) {
8932f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8945dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
8952f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8962f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8972f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
8982f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Currently, the dllimport attribute is ignored for inlined functions.
8992f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Warning is emitted.
9002f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (FD->isInline()) {
9012f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
9022f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
9032f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
9042f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
9052f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // The attribute is also overridden by a subsequent declaration as dllexport.
9062f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Warning is emitted.
9072f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
9082f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov       nextAttr = nextAttr->getNext()) {
9092f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    if (nextAttr->getKind() == AttributeList::AT_dllexport) {
9102f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
9112f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov      return;
9122f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    }
9132f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
9142f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
91540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  if (D->getAttr<DLLExportAttr>()) {
9162f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
9172f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
9182f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
9192f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
92040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DLLImportAttr());
9216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
923026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
9246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
925545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
9263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
9276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9297b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
9302f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Attribute can be applied only to functions or variables.
931026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (isa<VarDecl>(D)) {
93240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    D->addAttr(::new (S.Context) DLLExportAttr());
9332f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
9342f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
9352f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
936026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
9372f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (!FD) {
9382f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9395dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
9402f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
9412f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
9422f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
943bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // Currently, the dllexport attribute is ignored for inlined functions, unless
944bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // the -fkeep-inline-functions flag has been used. Warning is emitted;
9452f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (FD->isInline()) {
9462f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
9472f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
9482f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
9492f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
9502f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
95140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) DLLExportAttr());
9526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9546f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
9556f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                    Sema &S) {
9566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  // Attribute has 3 arguments.
9576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  if (Attr.getNumArgs() != 3) {
9586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
9596f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    return;
9606f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
9616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
9626f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  unsigned WGSize[3];
9636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  for (unsigned i = 0; i < 3; ++i) {
9646f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    Expr *E = static_cast<Expr *>(Attr.getArg(i));
9656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    llvm::APSInt ArgNum(32);
9666f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    if (!E->isIntegerConstantExpr(ArgNum, S.Context)) {
9676f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
9686f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman        << "reqd_work_group_size" << E->getSourceRange();
9696f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman      return;
9706f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    }
9716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    WGSize[i] = (unsigned) ArgNum.getZExtValue();
9726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  }
97340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
9746f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman                                                     WGSize[2]));
9756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman}
9766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
977026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
97817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
97917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
98017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
98117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
98217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
98317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
98417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
98517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
986797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
987797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
98817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
989797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
99017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
99117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
9921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
993797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  std::string SectionStr(SE->getStrData(), SE->getByteLength());
994797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner
995797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  // If the target wants to validate the section specifier, make it happen.
996797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  std::string Error = S.Context.Target.isValidSectionSpecifier(SectionStr);
997797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  if (Error.empty()) {
998797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    D->addAttr(::new (S.Context) SectionAttr(SectionStr));
999797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    return;
1000797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  }
10011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1002797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1003797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    << Error;
10041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
100517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
100617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
1007803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
10087b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute has no arguments.
1009545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
10103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
10116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10137b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
10147b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute can be applied only to functions.
10157b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (!isa<FunctionDecl>(d)) {
10167b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
10175dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
10187b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
10197b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
10207b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
10217b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // stdcall and fastcall attributes are mutually incompatible.
102240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  if (d->getAttr<FastCallAttr>()) {
10237b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
10247b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov      << "stdcall" << "fastcall";
10257b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
10267b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
10277b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
102840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) StdCallAttr());
10296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1031803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
10327b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute has no arguments.
1033545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
10343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
10356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10377b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
10387b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (!isa<FunctionDecl>(d)) {
10397b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
10405dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
10417b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
10427b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
10437b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
10447b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // stdcall and fastcall attributes are mutually incompatible.
104540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  if (d->getAttr<StdCallAttr>()) {
10467b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
10477b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov      << "fastcall" << "stdcall";
10487b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
10497b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
10507b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
105140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) FastCallAttr());
10526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1054803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
10556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1056545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
10573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
10586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1060bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
106140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) NoThrowAttr());
10626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1064232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1065232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1066232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
10673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1068232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1069232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1070bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
107140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) ConstAttr());
1072232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1073232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1074232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1075232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1076232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
10773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1078232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1079232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1080bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
108140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) PureAttr());
1082232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1083232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1084f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
108589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // Match gcc which ignores cleanup attrs when compiling C++.
108689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  if (S.getLangOptions().CPlusPlus)
108789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
1088bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1089bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  if (!Attr.getParameterName()) {
1090f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1091f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1092f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1093bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1094f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1095f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1096f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1097f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1098bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1099f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
1100bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1101f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1102f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1103f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1104f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1105bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1106f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
1107f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *CleanupDecl
1108f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1109f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall                         Sema::LookupOrdinaryName);
1110f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
111189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1112f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1113f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1114f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1115bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1116f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1117f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
111889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
1119f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1120f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1121f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1122f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1123f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
112489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
1125f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1126f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1127f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1128bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
112989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
113089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
113189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
113289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1133d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman  if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
1134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
113589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
113689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
113789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
113889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1139bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
114040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) CleanupAttr(FD));
1141f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1142f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1143bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1145bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
11465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Attr.getNumArgs() != 1) {
11475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
11495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
11505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
11515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
11525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << Attr.getName() << 0 /*function*/;
11535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
11545b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1155bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // FIXME: in C++ the implicit 'this' function parameter also counts.  this is
1156bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // needed in order to be compatible with GCC the index must start with 1.
11575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
11585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
11595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
11605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
11615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
11625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
11635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
11655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
11665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
11695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
11705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
11715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
11725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1175bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11765b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
11775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1178bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
11805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
11815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
11825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
11836217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
11845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
11855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1186bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
11875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
11885b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1189bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
11905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Ty = getFunctionOrMethodResultType(d);
11915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
11925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
11935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
11946217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
11955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
11965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
11985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
11995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1201bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
120240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
12035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
12045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
12052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind {
12062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  CFStringFormat,
12072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  NSStringFormat,
12082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  StrftimeFormat,
12092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  SupportedFormat,
12102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  InvalidFormat
12112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar};
12122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
12132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format
12142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types.
12152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
12162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for formats that get handled specially.
12172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "NSString")
12182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return NSStringFormat;
12192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "CFString")
12202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return CFStringFormat;
12212b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "strftime")
12222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return StrftimeFormat;
12232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
12242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Otherwise, check for supported formats.
12252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
12262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
12272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
12282b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      Format == "zcmn_err")
12292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    return SupportedFormat;
12302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
12312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  return InvalidFormat;
12322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}
12332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
1234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1235bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1236803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
12376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1238545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1239fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
12416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1244545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
12453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
12466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1249620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1250fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
12515dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
12526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12553568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
12566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
12576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  llvm::StringRef Format = Attr.getParameterName()->getNameStr();
12596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
12612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Format.startswith("__") && Format.endswith("__"))
12622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar    Format = Format.substr(2, Format.size() - 4);
12632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar
12642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  // Check for supported formats.
12652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  FormatAttrKind Kind = getFormatAttrKind(Format);
12662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == InvalidFormat) {
1267fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
12682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar      << "format" << Attr.getParameterName()->getNameStr();
12696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
1273545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1274803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1275803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1276fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
12773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
12786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12814fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  // FIXME: We should handle the implicit 'this' parameter in a more generic
12824fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  // way that can be used for other arguments.
12834fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  bool HasImplicitThisParam = false;
12844fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) {
12854fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson    if (MD->isInstance()) {
12864fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson      HasImplicitThisParam = true;
12874fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson      NumArgs++;
12884fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson    }
12894fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  }
12901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1292fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
12933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
12946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
12986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1299bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
13004fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson  if (HasImplicitThisParam) ArgIdx--;
13011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
13033568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
13046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == CFStringFormat) {
1306085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1307fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1308fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1309085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1310085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
13112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  } else if (Kind == NSStringFormat) {
1312390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1313390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1314803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1315390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1316fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1317fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
13186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1319bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
13206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
13216217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1322390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1323fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1324fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
13256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
1329545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1330803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1331803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1332fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
13346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
13386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
13393568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
13406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
13416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1342803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
13436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
13446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
13456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
13483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
13492b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  if (Kind == StrftimeFormat) {
13506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1351fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1352fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
13536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
13546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
13556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
13566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
13583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
13596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar  d->addAttr(::new (S.Context) FormatAttr(Format, Idx.getZExtValue(),
13632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar                                          FirstArg.getZExtValue()));
13646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13660b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
13670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
13686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1369545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
13703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
13716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
13750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
1376bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
13770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
13780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
13790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
13800c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = dyn_cast<RecordDecl>(d);
13810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
13820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1383fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
13845dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 1 /*union*/;
13856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1389bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
13900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
13910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
13920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
13930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
139417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
139517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
13960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
13970c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
13980c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
13990c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1400bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
14010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
14020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
14030c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (FirstType->isFloatingType() || FirstType->isVectorType()) {
1404bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
14050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor           diag::warn_transparent_union_attribute_floating);
14060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
14070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1408bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
14090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
14100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
14110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
14120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
14130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
14140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
14150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
14160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1417bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
14180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
1419bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
14200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
14210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
14220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1423bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
14240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
14250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
1426bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1427bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1428bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
14296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
143040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr());
14316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14330b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
14346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1435545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
14363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
14376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1439797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
1440797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1441bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
14436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
14446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
1445797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
14466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
144840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
14490b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner                                                        SE->getByteLength())));
14506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1452803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
14536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1454545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
14553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
14566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
14586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
1460545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
14616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
14627549c5589ac0d2087e55f2bdd4854adef23f29fdDaniel Dunbar    // (For now we just use 128 bits which is the maximum on X86).
14636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
146440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    d->addAttr(::new (S.Context) AlignedAttr(Align));
14656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1467bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
146849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
146949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
1470803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1471fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1472fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "aligned" << alignmentExpr->getSourceRange();
147349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
147449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
1475396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
1476bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
1477396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar      << alignmentExpr->getSourceRange();
1478396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
1479396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
1480396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
148140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
14826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1483fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1484bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive
1485bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
1486fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
1487bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
1488bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
1489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
14900b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1491fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
1492fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
1493fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1494fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
1495fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
14963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1497fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1498fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1499fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1500fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
1501fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
15020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1503fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1504fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1505210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar
1506210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  llvm::StringRef Str = Attr.getParameterName()->getNameStr();
1507fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1508fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
1509210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  if (Str.startswith("__") && Str.endswith("__"))
1510210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    Str = Str.substr(2, Str.size() - 4);
1511fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1512fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1513fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
151473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
1515210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar  switch (Str.size()) {
1516fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
151773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
151873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
151973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
152073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
152173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
152273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
152373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
152473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
152573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
152673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
152773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
152873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
152973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
153073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
153173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
153273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1533fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1534fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1535fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1536fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1537210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "word")
15380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1539210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    else if (Str == "byte")
15400b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1541fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1542fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
1543210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar    if (Str == "pointer")
15440b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1545fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1546fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1547fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1548fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
1549fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1550fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
1551fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1552fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
1553fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
1554fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1555fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1556fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1557fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
155873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1559183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
156073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
156173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
156273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isIntegralType())
156373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
156473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
156573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
156673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
156773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
156873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
156973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
157073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
157173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1572390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
1573390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
1574390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
1575390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
1576f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
1577f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
1578fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
1579fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
1580fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
15813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1582fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1583fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
15843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1585fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1586fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
158773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
158873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
158973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
159073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1591fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
15920b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
1593fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
15940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
1595fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1596fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
159773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
159873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
159973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
160073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1601fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
16020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
1603fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
16040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
1605fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1606fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
1607fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
16080b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
1609fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
16100b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
1611fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
16120b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
1613fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1614fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
1615fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
16160b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
1617fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
16180b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.LongLongTy;
1619fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
16200b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedLongLongTy;
1621fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
162273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
162373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
162473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1625f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
1626f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
1627f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1628f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
1629f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
1630f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
163173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1632fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1633fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
163473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
163573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
1636fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1637fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1638fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
1639fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1640fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    TD->setUnderlyingType(NewTy);
1641fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else
1642fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
1643fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
16440744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
16451feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1646d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
1647d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
1648d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1649d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1650d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1651e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
16525bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (!isFunctionOrMethod(d)) {
1653d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16545dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
1655d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1656d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1657bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16581feade8e520be483293dbf55eb57a51720899589Mike Stump  d->addAttr(::new (S.Context) NoDebugAttr());
1659d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
1660d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
16611feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
16625bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
16635bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
16645bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
16655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
16665bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1667bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1668c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
16695bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16705dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
16715bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
16725bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1673bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
16741feade8e520be483293dbf55eb57a51720899589Mike Stump  d->addAttr(::new (S.Context) NoInlineAttr());
16755bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
16765bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
1677cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
167826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
167926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
168026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
168126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
168226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
1683bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1684c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
1685c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
168626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16875dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
168826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
168926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
1690bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1691c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!Fn->isInline()) {
1692cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
1693c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
1694c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
1695bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
169640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) GNUInlineAttr());
169726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
169826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
1699ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1700ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  // check the attribute arguments.
1701ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (Attr.getNumArgs() != 1) {
170255d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1703ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
1704ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
170555d3aaf9a537888734762170823daf750ea9036dEli Friedman
1706ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (!isFunctionOrMethod(d)) {
1707ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
17085dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
1709ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
1710ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
171155d3aaf9a537888734762170823daf750ea9036dEli Friedman
171255d3aaf9a537888734762170823daf750ea9036dEli Friedman  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
171355d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
171455d3aaf9a537888734762170823daf750ea9036dEli Friedman  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
171555d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
171655d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
171755d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
171855d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
171955d3aaf9a537888734762170823daf750ea9036dEli Friedman
1720264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov  if (S.Context.Target.getRegParmMax() == 0) {
1721264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
172255d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
172355d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
172455d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
172555d3aaf9a537888734762170823daf750ea9036dEli Friedman
1726348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
1727264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
1728264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
172955d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
173055d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
173155d3aaf9a537888734762170823daf750ea9036dEli Friedman
173240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
1733ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
1734ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
17350744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
1736b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
1737b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
1738b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1739b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
1740b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek                                        Sema &S) {
1741b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
17425dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  QualType RetTy;
1743bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17445dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
17455dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = MD->getResultType();
17465dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
17475dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = FD->getResultType();
17485dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
174921531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    SourceLocation L = Attr.getLoc();
175021531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
175121531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek        << SourceRange(L, L) << Attr.getName() << 3 /* function or method */;
1752b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
1753b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
1754bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17556217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>()
1756183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall        || RetTy->getAs<ObjCObjectPointerType>())) {
175721531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    SourceLocation L = Attr.getLoc();
175821531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek    S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
175921531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek      << SourceRange(L, L) << Attr.getName();
1760bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
17615dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
1762bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1763b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  switch (Attr.getKind()) {
1764b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
1765b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
1766b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1767b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
176840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
1769b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1770b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
177140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
1772b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1773b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
1774b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
1775b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1776b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
17770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
17780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
17790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1780a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1781803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
1782803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it.
1783bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D,
1784bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump                                 const AttributeList &Attr, Sema &S) {
1785290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman  if (Attr.isDeclspecAttribute())
1786290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman    // FIXME: Try to deal with __declspec attributes!
1787290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman    return;
1788803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
17893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1790803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
1791ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
1792bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
1793bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
1794803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1795803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
17963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1797bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
1798af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
1799b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
1800bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
18013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
18023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1803803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
18043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1805803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
18063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
18073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
18089cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    HandleExtVectorTypeAttr(scope, D, Attr, S);
18093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
1810803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1811803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
18125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  case AttributeList::AT_format_arg:  HandleFormatArgAttr (D, Attr, S); break;
1813cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr(D, Attr, S); break;
18143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
181576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  case AttributeList::AT_malloc:      HandleMallocAttr    (D, Attr, S); break;
1816eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
18173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
18183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
1819b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1820b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
1821b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
1822b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
1823b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    HandleNSReturnsRetainedAttr(D, Attr, S); break;
1824b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
18256f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
18266f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    HandleReqdWorkGroupSize(D, Attr, S); break;
18276f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
18283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
182917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
18303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1831bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
183273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
1833b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  case AttributeList::AT_used:        HandleUsedAttr      (D, Attr, S); break;
18343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
18353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
1836026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
1837026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
18383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
18396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break;
1840803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
1841803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
1842803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
18430db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
18440db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
18450db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
1846f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1847fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  case AttributeList::AT_nsobject:    HandleObjCNSObject  (D, Attr, S); break;
18489eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1849770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1850232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1851232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1852f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  case AttributeList::AT_cleanup:     HandleCleanupAttr   (D, Attr, S); break;
18531feade8e520be483293dbf55eb57a51720899589Mike Stump  case AttributeList::AT_nodebug:     HandleNoDebugAttr   (D, Attr, S); break;
18541feade8e520be483293dbf55eb57a51720899589Mike Stump  case AttributeList::AT_noinline:    HandleNoInlineAttr  (D, Attr, S); break;
185555d3aaf9a537888734762170823daf750ea9036dEli Friedman  case AttributeList::AT_regparm:     HandleRegparmAttr   (D, Attr, S); break;
1856bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
18575e204486a7dd1e5f7e14e941a2c7e707a8ad1a3bChris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
185805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
185905f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
1860803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
1861d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1862803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1863803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1864803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1865803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1866803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1867803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
18689cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) {
1869803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  while (AttrList) {
18709cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttribute(S, D, *AttrList, *this);
1871803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    AttrList = AttrList->getNext();
1872803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1873803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1874803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1875e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
1876e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
18771eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
18787b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
1879e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
1880e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1881e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
1882e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
1883a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis                                FD->getType(), FD->getDeclaratorInfo());
1884e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1885e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
1886e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                           VD->getLocation(), II,
1887a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis                           VD->getType(), VD->getDeclaratorInfo(),
1888a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis                           VD->getStorageClass());
1889e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
1890e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
1891e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
1892e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
1893e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
1894e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
18957b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
1896c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getUsed()) return; // only do this once
1897c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  W.setUsed(true);
1898c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
1899c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    IdentifierInfo *NDId = ND->getIdentifier();
1900c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
1901c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NewD->addAttr(::new (Context) AliasAttr(NDId->getName()));
1902c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    NewD->addAttr(::new (Context) WeakAttr());
1903c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    WeakTopLevelDecl.push_back(NewD);
1904c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
1905c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    // to insert Decl at TU scope, sorry.
1906c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    DeclContext *SavedContext = CurContext;
1907c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = Context.getTranslationUnitDecl();
1908c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    PushOnScopeChains(NewD, S);
1909c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    CurContext = SavedContext;
1910c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner  } else { // just add weak to existing
1911c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner    ND->addAttr(::new (Context) WeakAttr());
1912e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
1913e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
1914e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
19150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
19160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
19170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
19189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
1919e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  // Handle #pragma weak
1920e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
1921e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    if (ND->hasLinkage()) {
1922e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier());
1923e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      if (W != WeakInfo()) {
19247b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn        // Identifier referenced by #pragma weak before it was declared
19257b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn        DeclApplyPragmaWeak(S, ND, W);
1926e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn        WeakUndeclaredIdentifiers[ND->getIdentifier()] = W;
1927e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
1928e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
1929e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
1930e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
19310744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
19320744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
19339cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
1934bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19350744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
19360744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
19370744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
19380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
19390744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
19400744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
19419cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      ProcessDeclAttributeList(S, D, Attrs);
1942bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19430744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
19440744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
19459cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
19460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
1947