SemaDeclAttr.cpp revision 2cff7d16fe58e6d6447ec9cad2af083beb20d6b5
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
44d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  return Ty->getAsFunctionType();
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) {
12714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  const ObjCObjectPointerType *PT = T->getAsObjCObjectPointerType();
128b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
130bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
131b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
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  }
440b109069995b44f3ef182bcd1b02ad05e9ea9d21dTed Kremenek
4412cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
4422cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek    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)) {
753897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    const FunctionType *FT = FD->getType()->getAsFunctionType();
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)
7786217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        : Ty->getAs<BlockPointerType>()->getPointeeType()->getAsFunctionType();
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  }
992797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner
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  }
1001797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner
1002797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1003797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    << Error;
1004797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner
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
110747b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor  NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
110847b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor                                        Sema::LookupOrdinaryName);
1109f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
111089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1111f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1112f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1113f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1114bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1115f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1116f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
111789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
1118f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1119f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1120f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1121f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1122f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
112389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
1124f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1125f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1126f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1127bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
112889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
112989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
113089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
113189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1132d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman  if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
1133bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
113489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
113589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
113689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
113789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
1138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
113940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) CleanupAttr(FD));
1140f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1141f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1142bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on
1143bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
11455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Attr.getNumArgs() != 1) {
11465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
11485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
11495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
11505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
11515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << Attr.getName() << 0 /*function*/;
11525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
11535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1154bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // FIXME: in C++ the implicit 'this' function parameter also counts.  this is
1155bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // needed in order to be compatible with GCC the index must start with 1.
11565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
11575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned FirstIdx = 1;
11585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // checks for the 2nd argument
11595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
11605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  llvm::APSInt Idx(32);
11615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
11625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
11645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
11655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
11685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
11695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    << "format" << 2 << IdxExpr->getSourceRange();
11705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
11715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  }
1172bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  unsigned ArgIdx = Idx.getZExtValue() - 1;
1174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  // make sure the format string is really a string
11765b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
11785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
11795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (not_nsstring_type &&
11805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
11815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
11826217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
11835b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
11845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1185bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "a string type" : "an NSString")
11865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
11875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1188bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
11895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  Ty = getFunctionOrMethodResultType(d);
11905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  if (!isNSStringType(Ty, S.Context) &&
11915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      !isCFStringType(Ty, S.Context) &&
11925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian      (!Ty->isPointerType() ||
11936217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
11945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    // FIXME: Should highlight the actual expression that has the wrong type.
11955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    << (not_nsstring_type ? "string type" : "NSString")
11975b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian       << IdxExpr->getSourceRange();
11985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian    return;
1199bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  }
1200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
120140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
12025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian}
12035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian
1204bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1206803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
12076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1208545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1209fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
12103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
12116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1214545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
12153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
12166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1219620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1220fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
12215dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
12226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1225bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // FIXME: in C++ the implicit 'this' function parameter also counts.  this is
1226bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // needed in order to be compatible with GCC the index must start in 1 and the
1227bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  // limit is numargs+1
12283568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
12296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
12306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1231545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  const char *Format = Attr.getParameterName()->getName();
1232545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  unsigned FormatLen = Attr.getParameterName()->getLength();
12336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
12356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
12366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
12376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Format += 2;
12386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    FormatLen -= 4;
12396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool Supported = false;
12426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_NSString = false;
12436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_strftime = false;
1244085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  bool is_CFString = false;
1245bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  switch (FormatLen) {
12476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  default: break;
1248803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 5: Supported = !memcmp(Format, "scanf", 5); break;
1249803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 6: Supported = !memcmp(Format, "printf", 6); break;
12504403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn  case 7: Supported = !memcmp(Format, "printf0", 7) ||
12514403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn                      !memcmp(Format, "strfmon", 7); break;
12526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  case 8:
1253085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
1254085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_NSString = !memcmp(Format, "NSString", 8)) ||
1255085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_CFString = !memcmp(Format, "CFString", 8));
12566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    break;
12576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1258bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Supported) {
1260fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1261fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "format" << Attr.getParameterName()->getName();
12626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
1266545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1267803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1268803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1269fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
12703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
12716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1275fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
12763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
12776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
12816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
1282bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
12836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
12843568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
12856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1286085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (is_CFString) {
1287085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1288fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1289fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1290085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1291085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
1292085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  } else if (is_NSString) {
1293390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1294390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1295803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1296390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1297fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1298fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
12996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
1300bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    }
13016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
13026217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1303390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1304fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1305fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
13066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
1310545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1311803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1312803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1313fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
13143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
13156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
13196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
13203568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
13216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
13226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1323803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
13246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
13256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
13266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
13293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
13306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_strftime) {
13316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1332fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1333fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
13346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
13356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
13366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
13376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1338fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
13393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
13406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
134340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
13446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                            Idx.getZExtValue(), FirstArg.getZExtValue()));
13456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
13466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
13480b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
13496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1350545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
13513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
13526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
13560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
1357bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
13580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
13590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
13600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
13610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = dyn_cast<RecordDecl>(d);
13620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
13630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1364fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
13655dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 1 /*union*/;
13666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
1370bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(),
13710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
13720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
13730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
13740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
137517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  RecordDecl::field_iterator Field = RD->field_begin(),
137617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                          FieldEnd = RD->field_end();
13770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
13780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
13790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
13800c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1381bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
13820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
13830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
13840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (FirstType->isFloatingType() || FirstType->isVectorType()) {
1385bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(FirstField->getLocation(),
13860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor           diag::warn_transparent_union_attribute_floating);
13870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
13880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1389bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
13900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
13910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
13920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
13930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
13940c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
13950c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
13960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
13970c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1398bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
13990c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
1400bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(Field->getLocation(),
14010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
14020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
14030c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1404bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump      S.Diag(FirstField->getLocation(),
14050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
14060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
1407bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1408bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1409bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
14106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
141140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  RD->addAttr(::new (S.Context) TransparentUnionAttr());
14126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
14156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1416545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
14173c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
14186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1420797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
1421797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1422bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
14236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
14246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
14256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
1426797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
14276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
142940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
14300b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner                                                        SE->getByteLength())));
14316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
14326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1433803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(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  }
14396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
14406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
1441545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
14426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
14437549c5589ac0d2087e55f2bdd4854adef23f29fdDaniel Dunbar    // (For now we just use 128 bits which is the maximum on X86).
14446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
144540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    d->addAttr(::new (S.Context) AlignedAttr(Align));
14466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
14476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1448bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
144949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
145049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
1451803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1452fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1453fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "aligned" << alignmentExpr->getSourceRange();
145449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
145549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
1456396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
1457bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
1458396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar      << alignmentExpr->getSourceRange();
1459396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
1460396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
1461396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
146240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
14636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1464fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1465bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive
1466bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type.
1467fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
1468bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a
1469bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
1470bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer.
14710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1472fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
1473fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
1474fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1475fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
1476fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
14773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1478fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1479fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1480fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1481fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
1482fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
14830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1484fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1485fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1486fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  const char *Str = Name->getName();
1487fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned Len = Name->getLength();
1488fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1489fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
1490fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
1491fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
1492fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Str += 2;
1493fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Len -= 4;
1494fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1495fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1496fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1497fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
149873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
1499fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (Len) {
1500fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
150173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
150273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
150373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
150473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
150573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
150673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
150773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
150873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
150973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
151073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
151173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
151273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
151373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
151473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
151573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
151673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1517fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1518fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1519fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1520fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1521fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "word", 4))
15220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1523fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "byte", 4))
15240b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1525fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1526fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
1527fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "pointer", 7))
15280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1529fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1530fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1531fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1532fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
1533fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1534fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
1535fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1536fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
1537fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
1538fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1539fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1540fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1541fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
154273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
154373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType())
154473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
154573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
154673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isIntegralType())
154773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
154873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
154973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
155073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
155173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
155273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
155373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
155473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
155573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1556390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
1557390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
1558390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
1559390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
1560f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
1561f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
1562fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
1563fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
1564fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
15653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1566fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1567fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
15683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1569fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1570fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
157173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
157273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
157373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
157473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1575fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
15760b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
1577fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
15780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
1579fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1580fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
158173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
158273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
158373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
158473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1585fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
15860b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
1587fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
15880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
1589fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1590fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
1591fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
15920b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
1593fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
15940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
1595fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
15960b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
1597fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1598fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
1599fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
16000b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
1601fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
16020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.LongLongTy;
1603fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
16040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedLongLongTy;
1605fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
160673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
160773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
160873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1609f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
1610f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
1611f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1612f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
1613f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
1614f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
161573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1616fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1617fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
161873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
161973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
1620fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1621fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1622fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
1623fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1624fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    TD->setUnderlyingType(NewTy);
1625fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else
1626fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
1627fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
16280744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1629d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlssonstatic void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1630d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
1631d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
1632d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1633d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1634d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1635e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
16365bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (!isFunctionOrMethod(d)) {
1637d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16385dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
1639d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1640d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1641bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
164240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) NodebugAttr());
1643d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
1644d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
16455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlssonstatic void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
16465bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
16475bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
16485bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
16495bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
16505bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1651bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1652c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
16535bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16545dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
16555bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
16565bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
1657bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
165840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) NoinlineAttr());
16595bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
16605bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
1661cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
166226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
166326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
166426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
166526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
166626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
1667bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1668c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
1669c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
167026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16715dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
167226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
167326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
1674bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1675c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!Fn->isInline()) {
1676cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
1677c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
1678c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
1679bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
168040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) GNUInlineAttr());
168126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
168226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
1683ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1684ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  // check the attribute arguments.
1685ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (Attr.getNumArgs() != 1) {
168655d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1687ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
1688ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
168955d3aaf9a537888734762170823daf750ea9036dEli Friedman
1690ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (!isFunctionOrMethod(d)) {
1691ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
16925dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
1693ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
1694ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
169555d3aaf9a537888734762170823daf750ea9036dEli Friedman
169655d3aaf9a537888734762170823daf750ea9036dEli Friedman  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
169755d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
169855d3aaf9a537888734762170823daf750ea9036dEli Friedman  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
169955d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
170055d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
170155d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
170255d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
170355d3aaf9a537888734762170823daf750ea9036dEli Friedman
1704264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov  if (S.Context.Target.getRegParmMax() == 0) {
1705264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
170655d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
170755d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
170855d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
170955d3aaf9a537888734762170823daf750ea9036dEli Friedman
1710348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
1711264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
1712264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
171355d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
171455d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
171555d3aaf9a537888734762170823daf750ea9036dEli Friedman
171640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
1717ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
1718ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
17190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
1720b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
1721b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
1722b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1723b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
1724b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek                                        Sema &S) {
1725b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
17265dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  QualType RetTy;
1727bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17285dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
17295dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = MD->getResultType();
17305dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
17315dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = FD->getResultType();
17325dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
17335dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
17345dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek        << Attr.getName() << 3 /* function or method */;
1735b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
1736b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
1737bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
17386217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>()
173914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        || RetTy->getAsObjCObjectPointerType())) {
17405dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
17415dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName();
1742bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    return;
17435dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
1744bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
1745b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  switch (Attr.getKind()) {
1746b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
1747b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
1748b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1749b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
175040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
1751b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1752b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
175340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
1754b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1755b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
1756b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
1757b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1758b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
17590744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
17600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
17610744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1762a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1763803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
1764803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it.
1765bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D,
1766bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump                                 const AttributeList &Attr, Sema &S) {
1767290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman  if (Attr.isDeclspecAttribute())
1768290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman    // FIXME: Try to deal with __declspec attributes!
1769290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman    return;
1770803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
17713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1772803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
1773ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
1774bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // Ignore these, these are type attributes, handled by
1775bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    // ProcessTypeAttributes.
1776803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1777803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
17783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1779bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::AT_always_inline:
1780af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
1781b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
1782bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
17833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
17843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1785803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
17863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1787803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
17883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
17893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
17909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    HandleExtVectorTypeAttr(scope, D, Attr, S);
17913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
1792803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1793803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
17945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian  case AttributeList::AT_format_arg:  HandleFormatArgAttr (D, Attr, S); break;
1795cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr(D, Attr, S); break;
17963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
179776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn  case AttributeList::AT_malloc:      HandleMallocAttr    (D, Attr, S); break;
1798eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
17993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
18003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
1801b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1802b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
1803b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
1804b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
1805b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    HandleNSReturnsRetainedAttr(D, Attr, S); break;
1806b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
18076f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman  case AttributeList::AT_reqd_wg_size:
18086f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman    HandleReqdWorkGroupSize(D, Attr, S); break;
18096f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman
18103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
181117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
18123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1813bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
181473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
1815b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  case AttributeList::AT_used:        HandleUsedAttr      (D, Attr, S); break;
18163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
18173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
1818026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
1819026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
18203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
18216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break;
1822803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
1823803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
1824803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
18250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
18260db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
18270db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
1828f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1829fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  case AttributeList::AT_nsobject:    HandleObjCNSObject  (D, Attr, S); break;
18309eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1831770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1832232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1833232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1834f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  case AttributeList::AT_cleanup:     HandleCleanupAttr   (D, Attr, S); break;
1835d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  case AttributeList::AT_nodebug:     HandleNodebugAttr   (D, Attr, S); break;
18365bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  case AttributeList::AT_noinline:    HandleNoinlineAttr  (D, Attr, S); break;
183755d3aaf9a537888734762170823daf750ea9036dEli Friedman  case AttributeList::AT_regparm:     HandleRegparmAttr   (D, Attr, S); break;
1838bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump  case AttributeList::IgnoredAttribute:
18395e204486a7dd1e5f7e14e941a2c7e707a8ad1a3bChris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
184005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
184105f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
1842803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
1843d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1844803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1845803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1846803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1847803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1848803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1849803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
18509cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) {
1851803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  while (AttrList) {
18529cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttribute(S, D, *AttrList, *this);
1853803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    AttrList = AttrList->getNext();
1854803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1855803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1856803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1857e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition),
1858e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one
18597b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan FlynnNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II)
1860e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn{
18617b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
1862e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  NamedDecl *NewD = 0;
1863e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1864e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
1865e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getLocation(), DeclarationName(II),
1866e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                                FD->getType());
1867e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1868e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
1869e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                           VD->getLocation(), II,
1870e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn                           VD->getType(), VD->getStorageClass());
1871e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
1872e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  return NewD;
1873e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
1874e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
1875e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
1876e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias.
18777b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
1878e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (!W.getUsed()) { // only do this once
1879e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    W.setUsed(true);
1880e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
1881e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      IdentifierInfo *NDId = ND->getIdentifier();
1882e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
1883e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      NewD->addAttr(::new (Context) AliasAttr(NDId->getName()));
1884e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      NewD->addAttr(::new (Context) WeakAttr());
18857b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn      WeakTopLevelDecl.push_back(NewD);
18867b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn      // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
18877b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn      // to insert Decl at TU scope, sorry.
18887b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn      DeclContext *SavedContext = CurContext;
18897b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn      CurContext = Context.getTranslationUnitDecl();
18907b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn      PushOnScopeChains(NewD, S);
18917b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn      CurContext = SavedContext;
1892e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    } else { // just add weak to existing
1893e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      ND->addAttr(::new (Context) WeakAttr());
1894e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
1895e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
1896e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn}
1897e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
18980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
18990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
19000744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
19019cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
1902e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  // Handle #pragma weak
1903e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
1904e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    if (ND->hasLinkage()) {
1905e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier());
1906e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      if (W != WeakInfo()) {
19077b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn        // Identifier referenced by #pragma weak before it was declared
19087b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn        DeclApplyPragmaWeak(S, ND, W);
1909e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn        WeakUndeclaredIdentifiers[ND->getIdentifier()] = W;
1910e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn      }
1911e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn    }
1912e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn  }
1913e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn
19140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
19150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
19169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
1917bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
19190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
19200744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
19210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
19220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
19230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
19249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      ProcessDeclAttributeList(S, D, Attrs);
1925bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump
19260744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
19270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
19289cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(S, D, Attrs);
19290744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
1930