SemaDeclAttr.cpp revision acc5f3e42334525bf28c86471551f83dfce222d5
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"
18e4858a65a93fb36c099d8dd2ea0a98e33e77687eDaniel Dunbar#include "clang/Basic/Diagnostic.h"
19fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2012bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h"
216e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek#include <llvm/ADT/StringExtras.h>
226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
27e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic const FunctionTypeProto *getFunctionProto(Decl *d) {
296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = Ty->getAsPointerType()->getPointeeType();
416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (const FunctionType *FnTy = Ty->getAsFunctionType())
436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType());
446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return 0;
466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
49b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const PointerType *PT = T->getAsPointerType();
50b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
53b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!ClsT)
556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
64e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
65e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
66e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
67e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
72803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
73803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner                                    Sema &S) {
74545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
75545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
76803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
77545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
82545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
83803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
84803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
87545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
89803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
90803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
91803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "ext_vector_type", sizeExpr->getSourceRange());
926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // in conjunction with complex types (pointers, arrays, functions, etc.).
96b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!curType->isIntegerType() && !curType->isRealFloatingType()) {
97803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
98b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner           curType.getAsString());
996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, the size is specified as the
1026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // number of elements, not the number of bytes.
1036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
1046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
106803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
107803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           sizeExpr->getSourceRange());
1086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Instantiate/Install the vector type, the number of elements is > 0.
111803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
1126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Remember this typedef decl, we will need it later for diagnostics.
113803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  S.ExtVectorDecls.push_back(tDecl);
1146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
116065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
117065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to
118065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function
119065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates
120065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a
121065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar.
122065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size
123065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well
124065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type.
125803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
126065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  QualType CurType;
127065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
128065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = VD->getType();
129065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
130065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = TD->getUnderlyingType();
131065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else {
132803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl,
133803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("vector_size"),
134803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           SourceRange(Attr.getLoc(), Attr.getLoc()));
135065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
136065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  }
137065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
138065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Check the attribute arugments.
139545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
140803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
141803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
142065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
144545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
146803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
147803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
148803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "vector_size", sizeExpr->getSourceRange());
149065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // navigate to the base type - we need to provide for vector pointers,
1526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vector arrays, and functions returning vectors.
153b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (CurType->isPointerType() || CurType->isArrayType() ||
154b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner      CurType->isFunctionType()) {
1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    assert(0 && "HandleVector(): Complex type construction unimplemented");
1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     do {
1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     if (PointerType *PT = dyn_cast<PointerType>(canonType))
1596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = PT->getPointeeType().getTypePtr();
1606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
1616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = AT->getElementType().getTypePtr();
1626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
1636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = FT->getResultType().getTypePtr();
1646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     } while (canonType->isPointerType() || canonType->isArrayType() ||
1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType->isFunctionType());
1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     */
1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the base type must be integer or float.
169b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
170803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
171b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner           CurType.getAsString());
172065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
174803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vecSize is specified in bytes - convert to bits.
1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the vector size needs to be an integral multiple of the type size.
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize % typeSize) {
180803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size,
181803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           sizeExpr->getSourceRange());
182065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
185803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
186803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           sizeExpr->getSourceRange());
187065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
189065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
190065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Success! Instantiate the vector type, the number of elements is > 0, and
191065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // not required to be a power of 2, unlike GCC.
192803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
193065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
194065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
195065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    VD->setType(CurType);
196065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else
197065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    cast<TypedefDecl>(D)->setUnderlyingType(CurType);
1986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
200803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
202545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
203803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
204803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
20949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    TD->addAttr(new PackedAttr());
2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
214803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
215803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(Attr.getLoc(),
216803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner             diag::warn_attribute_ignored_for_field_of_type,
217803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner             Attr.getName()->getName(), FD->getType().getAsString());
2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
21949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner      FD->addAttr(new PackedAttr());
2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
221803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored,
222803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           Attr.getName()->getName());
2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
22696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
22796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
22896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
22996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek           std::string("0"));
23096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
23196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
23296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
23396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // The IBOutlet attribute only applies to instance variables of Objective-C
23496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // classes.
23596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d))
23696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    ID->addAttr(new IBOutletAttr());
23796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  else
23896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar);
23996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
24096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
241eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
242eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
243eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // GCC ignores the nonnull attribute on K&R style function
244eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // prototypes, so we ignore it as well
245eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  const FunctionTypeProto *proto = getFunctionProto(d);
246eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  if (!proto) {
247eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
248eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek           "nonnull", "function");
249eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
250eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
251eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
252eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  unsigned NumArgs = proto->getNumArgs();
253eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
254eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
255eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
256eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
257eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
258eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
259eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
260eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
261eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
262eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    Expr *Ex = static_cast<Expr *>(Attr.getArg(0));
263eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
264eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
265eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
266eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek             "nonnull", Ex->getSourceRange());
267eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
268eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
269eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
270eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
271eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
272eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
273eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
2746e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek             "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange());
275eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
276eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
277465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek
278465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
279eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
280eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
281b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner    if (!proto->getArgType(x)->isPointerType()) {
282eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
283eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only,
284eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek             "nonnull", Ex->getSourceRange());
285eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
286eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
287eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
288eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
289eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
290eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
291eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  if (!NonNullArgs.empty()) {
292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned* start = &NonNullArgs[0];
293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned size = NonNullArgs.size();
294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    std::sort(start, start + size);
295eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    d->addAttr(new NonNullAttr(start, size));
296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  else
298eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    d->addAttr(new NonNullAttr());
299eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
300eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
301803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
303545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
304803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
305803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
3066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
309545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
3106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
3116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
3126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
314803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
315803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "alias", std::string("1"));
3166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *Alias = Str->getStrData();
3206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned AliasLen = Str->getByteLength();
3216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
3236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
3256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
327803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
329545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
330803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
331803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
3326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
3366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Fn) {
337803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
338803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "noreturn", "function");
3396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoReturnAttr());
3436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
34573798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
34673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
34773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
34873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
34973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek           std::string("0"));
35073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
35173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
35273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
353356b63a6668d8b010b53921941576189ee4bd459Ted Kremenek  if (!isa<VarDecl>(d) && !getFunctionProto(d)) {
35473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
355356b63a6668d8b010b53921941576189ee4bd459Ted Kremenek           "unused", "variable and function");
35673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
35773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
35873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
35973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  d->addAttr(new UnusedAttr());
36073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
36173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
3623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
3643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
3653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
3663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
3673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
3683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
3693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
3703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
3713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
3723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
3733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
3743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
3753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar             "constructor", "1", E->getSourceRange());
3763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
3773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
3783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
3793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
3803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
3813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
3823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (!Fn) {
3833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
3843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar           "constructor", "function");
3853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
3863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
3873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
3883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  d->addAttr(new ConstructorAttr(priority));
3893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
3903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
3913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
3933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
3943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
3953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
3963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
3973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
3983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
3993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
4003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
4013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
4023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
4033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
4043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar             "destructor", "1", E->getSourceRange());
4053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
4063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
4073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
4083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
4113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (!Fn) {
4123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
4133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar           "destructor", "function");
4143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  d->addAttr(new DestructorAttr(priority));
4183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
4193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
420803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
422545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
423803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
424803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DeprecatedAttr());
4296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
431803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
433545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
434803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
435803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
4366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
439545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
4406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
4416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
4426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
444803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
445803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "visibility", std::string("1"));
4466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *TypeStr = Str->getStrData();
4506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned TypeLen = Str->getByteLength();
4516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  VisibilityAttr::VisibilityTypes type;
4526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
4546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::DefaultVisibility;
4556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
4566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility;
4576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
4586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility; // FIXME
4596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
4606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::ProtectedVisibility;
4616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
462803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
463803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "visibility", TypeStr);
4646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new VisibilityAttr(type));
4686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
470803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
472545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
473803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
474803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new WeakAttr());
4796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
481803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
483545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
484803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
485803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLImportAttr());
4906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
492803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
494545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
495803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
496803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLExportAttr());
5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
503803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
505545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
506803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
507803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
5086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new StdCallAttr());
5126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
514803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
516545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
517803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
518803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
5196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FastCallAttr());
5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
525803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
527545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
528803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
529803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoThrowAttr());
5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes
5376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
538803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
540545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
541803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
5426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("1"));
5436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
546545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
547803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
548803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("3"));
5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // GCC ignores the format attribute on K&R style function
5536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // prototypes, so we ignore it as well
5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const FunctionTypeProto *proto = getFunctionProto(d);
5556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!proto) {
557803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
558803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "format", "function");
5596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: in C++ the implicit 'this' function parameter also counts.
5636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // this is needed in order to be compatible with GCC
5646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the index must start in 1 and the limit is numargs+1
5656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned NumArgs  = proto->getNumArgs();
5666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
5676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
568545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  const char *Format = Attr.getParameterName()->getName();
569545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  unsigned FormatLen = Attr.getParameterName()->getLength();
5706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
5726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
5736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
5746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Format += 2;
5756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    FormatLen -= 4;
5766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool Supported = false;
5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_NSString = false;
5806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_strftime = false;
5816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  switch (FormatLen) {
5836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  default: break;
584803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 5: Supported = !memcmp(Format, "scanf", 5); break;
585803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 6: Supported = !memcmp(Format, "printf", 6); break;
586803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  case 8:
5886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
5896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                (is_NSString = !memcmp(Format, "NSString", 8));
5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    break;
5916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Supported) {
594803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
595545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner           "format", Attr.getParameterName()->getName());
5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
600545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
601803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
602803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
603803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
6046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("2"), IdxExpr->getSourceRange());
6056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
609803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
6106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("2"), IdxExpr->getSourceRange());
6116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
6156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
6186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty = proto->getArgType(ArgIdx);
6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_NSString) {
6216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: do we need to check if the type is NSString*?  What are
6226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    //  the semantics?
623803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
6246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // FIXME: Should highlight the actual expression that has the
6256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // wrong type.
626803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString,
627803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner             IdxExpr->getSourceRange());
6286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
6296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
6306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
6316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
6326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: Should highlight the actual expression that has the
6336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // wrong type.
634803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string,
635803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           IdxExpr->getSourceRange());
6366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
640545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
641803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
642803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
643803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
6446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("3"), FirstArgExpr->getSourceRange());
6456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
6496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
6506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (proto->isVariadic()) {
6516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
6526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
653803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
6546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
6556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
6566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any variable
6596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the input is just the current time + the format string
6606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_strftime) {
6616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
662803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter,
6636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             FirstArgExpr->getSourceRange());
6646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
6656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
6666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
6676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
668803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("3"), FirstArgExpr->getSourceRange());
6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
6746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                            Idx.getZExtValue(), FirstArg.getZExtValue()));
6756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
6780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
6796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
680545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
6810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
6826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         std::string("0"));
6836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  TypeDecl *decl = dyn_cast<TypeDecl>(d);
6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner  if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) {
6890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
6906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         "transparent_union", "union");
6916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  //QualType QTy = Context.getTypeDeclType(decl);
6956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  //const RecordType *Ty = QTy->getAsUnionType();
6966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// FIXME
6986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// Ty->addAttr(new TransparentUnionAttr());
6996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
7026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
703545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
7040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
7050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           std::string("1"));
7066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
708545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
7096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
7106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
7136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
7140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                                          SE->getByteLength())));
7196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
721803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
7226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
723545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
724803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
725803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
7266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
730545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
7316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
7326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // (For now we just use 128 bits which is the maximum on X86.
7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
73649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner
73749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
73849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
739803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
740803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
741803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "aligned", alignmentExpr->getSourceRange());
74249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
74349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
74449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
7456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
7470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with
748065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type.
749fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
750fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute,
751fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer.
753fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
7540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
755fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
756fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
757fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
758fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
7600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
7610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           std::string("0"));
762fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
763fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
764fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
765fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
7670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
770fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  const char *Str = Name->getName();
771fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned Len = Name->getLength();
772fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
773fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
775fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
776fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Str += 2;
777fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Len -= 4;
778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
779fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
780fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
781fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (Len) {
783fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
784fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
785fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
786fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
787fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
788fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
789fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
790fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
791fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
792fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
793fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
794fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
795fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
796fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
797fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "word", 4))
7980b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
799fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "byte", 4))
8000b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
801fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
802fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
803fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "pointer", 7))
8040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
805fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
806fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
807fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
808fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
809fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
810fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
811fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
812fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
813fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
8140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode",
8150b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           SourceRange(Attr.getLoc(), Attr.getLoc()));
816fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
817fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
818fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
819fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // FIXME: Need proper fixed-width types
820fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
821fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
822fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
8230b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
824fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
825fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
8260b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
827fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
828fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
829fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
830fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
8310b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
832fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
8330b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
834fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
835fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
836fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
837fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
8380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
839fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
8400b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
841fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
842fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
843fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
8440b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
845fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
8460b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
847fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
8480b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
849fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
850fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
851fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
8520b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
853fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
8540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.LongLongTy;
855fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
8560b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedLongLongTy;
857fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
858fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
859fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
860fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!OldTy->getAsBuiltinType())
8610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
862fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (!(IntegerMode && OldTy->isIntegerType()) &&
863fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner           !(!IntegerMode && OldTy->isFloatingType())) {
8640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
865fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
866fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
867fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
868fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
869fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    TD->setUnderlyingType(NewTy);
870fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else
871fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
872fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
8730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
8740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
8750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
8760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
8770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
878803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
879803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
880803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it.
881803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
882803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
8833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
884803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
885803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
886803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
887803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
8883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
8893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
8903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
891803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
8923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
893803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
8943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
8953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
8963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    HandleExtVectorTypeAttr(D, Attr, S);
8973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
898803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
899803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
9003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
901eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
9023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
9033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
9043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
9053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
90673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
9073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
9083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
9093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
910803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
911803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
912803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
913803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
914803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0
915803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // TODO: when we have the full set of attributes, warn about unknown ones.
916803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr->getLoc(), diag::warn_attribute_ignored,
917803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           Attr->getName()->getName());
918803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif
919803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
920803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
921803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
922803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
923803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
924803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
925803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
926803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  while (AttrList) {
927803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    ProcessDeclAttribute(D, *AttrList, *this);
928803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    AttrList = AttrList->getNext();
929803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
930803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
931803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
932803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
9330744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
9340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
9350744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
9360744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
9370744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
9380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
9390744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
940803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
9410744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
9420744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
9430744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
9440744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
9450744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
9460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
9470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner      ProcessDeclAttributeList(D, Attrs);
9480744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
9490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
9500744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
9510744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
9520744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
9530744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
954