SemaDeclAttr.cpp revision 3568249c2d72d58b835a22d9186f5a6b4fc4bcd6
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
483568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
493568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
503568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar/// isFunctionOrMethod - Return true if the given decl is a (non-K&R)
523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar/// function or an Objective-C method.
533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethod(Decl *d) {
543568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  return getFunctionProto(d) || isa<ObjCMethodDecl>(d);
553568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
563568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic unsigned getFunctionOrMethodNumArgs(Decl *d) {
593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  if (const FunctionTypeProto *proto = getFunctionProto(d)) {
603568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->getNumArgs();
613568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  } else {
623568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->getNumParams();
633568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
643568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
653568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
663568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) {
673568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  if (const FunctionTypeProto *proto = getFunctionProto(d)) {
683568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->getArgType(Idx);
693568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  } else {
703568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->getParamDecl(Idx)->getType();
713568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
723568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethodVariadic(Decl *d) {
753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  if (const FunctionTypeProto *proto = getFunctionProto(d)) {
763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  } else {
783568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->isVariadic();
793568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
803568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
813568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
83b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const PointerType *PT = T->getAsPointerType();
84b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
87b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!ClsT)
896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
98085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
99085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const PointerType *PT = T->getAsPointerType();
100085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
101085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
102085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
103085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordType *RT = PT->getPointeeType()->getAsRecordType();
104085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
105085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
106085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
107085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
108085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (RD->getTagKind() != TagDecl::TK_struct)
109085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
110085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
111085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
112085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
113085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
114e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
115e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
116e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
117e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
1183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
1193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
1203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
1213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
122803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
123803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner                                    Sema &S) {
124545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
125545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
126803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
127545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
1286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
1316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
132545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
133803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
134803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
1356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
137545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
1386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
139803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
140803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
141803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "ext_vector_type", sizeExpr->getSourceRange());
1426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // in conjunction with complex types (pointers, arrays, functions, etc.).
146b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!curType->isIntegerType() && !curType->isRealFloatingType()) {
147803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
148b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner           curType.getAsString());
1496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, the size is specified as the
1526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // number of elements, not the number of bytes.
1536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
1546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
156803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
157803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           sizeExpr->getSourceRange());
1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Instantiate/Install the vector type, the number of elements is > 0.
161803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
1626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Remember this typedef decl, we will need it later for diagnostics.
163803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  S.ExtVectorDecls.push_back(tDecl);
1646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
166065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
167065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to
168065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function
169065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates
170065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a
171065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar.
172065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size
173065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well
174065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type.
175803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
176065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  QualType CurType;
177065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
178065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = VD->getType();
179065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
180065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = TD->getUnderlyingType();
181065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else {
182803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl,
183803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("vector_size"),
184803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           SourceRange(Attr.getLoc(), Attr.getLoc()));
185065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
186065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  }
187065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
188065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Check the attribute arugments.
189545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
190803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
191803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
192065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
194545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
1956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
196803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
197803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
198803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "vector_size", sizeExpr->getSourceRange());
199065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // navigate to the base type - we need to provide for vector pointers,
2026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vector arrays, and functions returning vectors.
203b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (CurType->isPointerType() || CurType->isArrayType() ||
204b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner      CurType->isFunctionType()) {
2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    assert(0 && "HandleVector(): Complex type construction unimplemented");
2066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     do {
2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     if (PointerType *PT = dyn_cast<PointerType>(canonType))
2096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = PT->getPointeeType().getTypePtr();
2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = AT->getElementType().getTypePtr();
2126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = FT->getResultType().getTypePtr();
2146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     } while (canonType->isPointerType() || canonType->isArrayType() ||
2156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType->isFunctionType());
2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     */
2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the base type must be integer or float.
219b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
220803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
221b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner           CurType.getAsString());
222065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
224803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
2256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vecSize is specified in bytes - convert to bits.
2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the vector size needs to be an integral multiple of the type size.
2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize % typeSize) {
230803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size,
231803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           sizeExpr->getSourceRange());
232065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
235803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
236803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           sizeExpr->getSourceRange());
237065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
239065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
240065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Success! Instantiate the vector type, the number of elements is > 0, and
241065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // not required to be a power of 2, unlike GCC.
242803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
243065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
244065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
245065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    VD->setType(CurType);
246065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else
247065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    cast<TypedefDecl>(D)->setUnderlyingType(CurType);
2486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
250803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
252545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
253803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
254803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
2556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
25949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    TD->addAttr(new PackedAttr());
2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
264803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
265803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(Attr.getLoc(),
266803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner             diag::warn_attribute_ignored_for_field_of_type,
267803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner             Attr.getName()->getName(), FD->getType().getAsString());
2686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
26949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner      FD->addAttr(new PackedAttr());
2706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
271803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored,
272803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           Attr.getName()->getName());
2736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
27596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
27696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
27796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
27896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
27996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek           std::string("0"));
28096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
28196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
28296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
28396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // The IBOutlet attribute only applies to instance variables of Objective-C
28496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // classes.
28596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d))
28696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    ID->addAttr(new IBOutletAttr());
28796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  else
28896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar);
28996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
29096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
291eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // GCC ignores the nonnull attribute on K&R style function
294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // prototypes, so we ignore it as well
295eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  const FunctionTypeProto *proto = getFunctionProto(d);
296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  if (!proto) {
297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
298eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek           "nonnull", "function");
299eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
300eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
301eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
302eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  unsigned NumArgs = proto->getNumArgs();
303eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
304eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
305eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
306eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
307eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
308eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
309eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
310eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
311eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
312eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    Expr *Ex = static_cast<Expr *>(Attr.getArg(0));
313eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
314eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
315eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
316eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek             "nonnull", Ex->getSourceRange());
317eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
318eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
319eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
320eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
321eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
322eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
3246e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek             "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange());
325eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
326eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
327465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek
328465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
331b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner    if (!proto->getArgType(x)->isPointerType()) {
332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
333eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only,
334eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek             "nonnull", Ex->getSourceRange());
3357fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
338eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
339eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
340eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
3417fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  // If no arguments were specified to __attribute__((nonnull)) then all
3427fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  // pointer arguments have a nonnull attribute.
3437fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
3447fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    unsigned idx = 0;
3457fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3467fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    for (FunctionTypeProto::arg_type_iterator
3477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek         I=proto->arg_type_begin(), E=proto->arg_type_end(); I!=E; ++I, ++idx)
3487fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      if ((*I)->isPointerType())
3497fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek        NonNullArgs.push_back(idx);
3507fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3517fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    if (NonNullArgs.empty()) {
3527fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
3537fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
3547fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    }
355eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
3567fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3577fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
3587fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
3597fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  std::sort(start, start + size);
3607fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  d->addAttr(new NonNullAttr(start, size));
361eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
362eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
363803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
365545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
366803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
367803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
3686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
371545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
3726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
3736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
3746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
376803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
377803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "alias", std::string("1"));
3786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *Alias = Str->getStrData();
3826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned AliasLen = Str->getByteLength();
3836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
3856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
3876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
389803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
391545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
392803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
393803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
3946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3973568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  if (!isa<FunctionDecl>(d) && !isa<ObjCMethodDecl>(d)) {
398803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
399803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "noreturn", "function");
4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoReturnAttr());
4046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
40673798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
40773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
40873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
40973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
41073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek           std::string("0"));
41173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
41273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
41373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
414356b63a6668d8b010b53921941576189ee4bd459Ted Kremenek  if (!isa<VarDecl>(d) && !getFunctionProto(d)) {
41573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
416356b63a6668d8b010b53921941576189ee4bd459Ted Kremenek           "unused", "variable and function");
41773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
41873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
41973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
42073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  d->addAttr(new UnusedAttr());
42173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
42273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
4233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
4253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
4263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
4273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
4313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
4323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
4333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
4343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
4353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
4363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar             "constructor", "1", E->getSourceRange());
4373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
4383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
4393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
4403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
4433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (!Fn) {
4443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
4453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar           "constructor", "function");
4463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  d->addAttr(new ConstructorAttr(priority));
4503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
4513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
4543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
4553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
4563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
4603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
4613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
4623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
4633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
4643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
4653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar             "destructor", "1", E->getSourceRange());
4663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
4673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
4683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
4693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4716782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
4723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
4733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar           "destructor", "function");
4743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  d->addAttr(new DestructorAttr(priority));
4783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
4793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
480803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
482545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
483803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
484803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DeprecatedAttr());
4896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
491803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
493545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
494803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
495803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
4966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
499545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
504803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
505803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "visibility", std::string("1"));
5066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *TypeStr = Str->getStrData();
5106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned TypeLen = Str->getByteLength();
5116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  VisibilityAttr::VisibilityTypes type;
5126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
5146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::DefaultVisibility;
5156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
5166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility;
5176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
5186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility; // FIXME
5196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::ProtectedVisibility;
5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
522803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
523803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "visibility", TypeStr);
5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new VisibilityAttr(type));
5286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
530aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlssonstatic void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5316e14a8f2ac4af8e3741eac8e9dccec0061bc7166Anders Carlsson  if (!Attr.getParameterName()) {
532aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
533aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson           "objc_gc", std::string("1"));
534aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
535aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
536aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
537aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  if (Attr.getNumArgs() != 0) {
538aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
539aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson           std::string("1"));
540aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
541aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
542aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
543aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  const char *TypeStr = Attr.getParameterName()->getName();
544aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  unsigned TypeLen = Attr.getParameterName()->getLength();
545aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
546aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  ObjCGCAttr::GCAttrTypes type;
547aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
548aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  if (TypeLen == 4 && !memcmp(TypeStr, "weak", 4))
549aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    type = ObjCGCAttr::Weak;
5506e14a8f2ac4af8e3741eac8e9dccec0061bc7166Anders Carlsson  else if (TypeLen == 6 && !memcmp(TypeStr, "strong", 6))
551aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    type = ObjCGCAttr::Strong;
552aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  else {
553aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
554aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson           "objc_gc", TypeStr);
555aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
556aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
557aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
558aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  d->addAttr(new ObjCGCAttr(type));
559aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson}
560aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
5619eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (!Attr.getParameterName()) {
5639eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
5649eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff           "blocks", std::string("1"));
5659eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
5669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
5679eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
5689eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
5699eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
5709eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff           std::string("1"));
5719eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
5729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
5739eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  const char *TypeStr = Attr.getParameterName()->getName();
5749eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  unsigned TypeLen = Attr.getParameterName()->getLength();
5759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
5769eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  BlocksAttr::BlocksAttrTypes type;
5779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
5789eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (TypeLen == 5 && !memcmp(TypeStr, "byref", 5))
5799eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
5809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
5819eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
5829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff           "blocks", TypeStr);
5839eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
5849eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
5859eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
5869eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  d->addAttr(new BlocksAttr(type));
5879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
5889eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
589803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
591545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
592803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
593803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
5946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new WeakAttr());
5986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
600803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
602545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
603803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
604803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
6056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLImportAttr());
6096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
611803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
613545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
614803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
615803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLExportAttr());
6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
622803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
624545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
625803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
626803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
6276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new StdCallAttr());
6316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
633803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
635545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
636803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
637803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
6386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FastCallAttr());
6426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
644803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
646545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
647803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
648803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
6496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoThrowAttr());
6536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes
6566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
657803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
659545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
660803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
6616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("1"));
6626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
665545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
666803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
667803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("3"));
6686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // GCC ignores the format attribute on K&R style function
6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // prototypes, so we ignore it as well
6733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  if (!isFunctionOrMethod(d)) {
674803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
675803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "format", "function");
6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: in C++ the implicit 'this' function parameter also counts.
6806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // this is needed in order to be compatible with GCC
6816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the index must start in 1 and the limit is numargs+1
6823568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
6836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
6846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
685545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  const char *Format = Attr.getParameterName()->getName();
686545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  unsigned FormatLen = Attr.getParameterName()->getLength();
6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
6896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
6906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
6916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Format += 2;
6926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    FormatLen -= 4;
6936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool Supported = false;
6966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_NSString = false;
6976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_strftime = false;
698085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  bool is_CFString = false;
6996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  switch (FormatLen) {
7016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  default: break;
702803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 5: Supported = !memcmp(Format, "scanf", 5); break;
703803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 6: Supported = !memcmp(Format, "printf", 6); break;
704803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
7056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  case 8:
706085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
707085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_NSString = !memcmp(Format, "NSString", 8)) ||
708085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_CFString = !memcmp(Format, "CFString", 8));
7096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    break;
7106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Supported) {
713803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
714545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner           "format", Attr.getParameterName()->getName());
7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
719545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
720803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
721803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
722803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
7236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("2"), IdxExpr->getSourceRange());
7246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
728803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("2"), IdxExpr->getSourceRange());
7306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
7356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
7373568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
7386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
739085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (is_CFString) {
740085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
741085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
742085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar             "a CFString", IdxExpr->getSourceRange());
743085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
744085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
745085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  } else if (is_NSString) {
7466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: do we need to check if the type is NSString*?  What are
7476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    //  the semantics?
748803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
7496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // FIXME: Should highlight the actual expression that has the
7506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // wrong type.
751085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
752085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar             "an NSString", IdxExpr->getSourceRange());
7536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
7546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
7556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
7566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
7576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: Should highlight the actual expression that has the
7586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // wrong type.
759085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
760085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar           "a string type", IdxExpr->getSourceRange());
7616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
765545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
766803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
767803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
768803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
7696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("3"), FirstArgExpr->getSourceRange());
7706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
7746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
7753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
7766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
7776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
778803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
7796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
7806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
7816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any variable
7846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the input is just the current time + the format string
7856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_strftime) {
7866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
787803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter,
7886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             FirstArgExpr->getSourceRange());
7896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
7906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
7916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
7926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
793803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
7946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("3"), FirstArgExpr->getSourceRange());
7956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
7996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                            Idx.getZExtValue(), FirstArg.getZExtValue()));
8006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
8030b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
8046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
805545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8060b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
8076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         std::string("0"));
8086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
811bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This shouldn't be restricted to typedefs
812bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
813bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  if (!TD || !TD->getUnderlyingType()->isUnionType()) {
8140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
8156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         "transparent_union", "union");
8166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
819bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
820bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
821bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: Should we do a check for RD->isDefinition()?
822bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
823bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This isn't supposed to be restricted to pointers, but otherwise
824bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // we might silently generate incorrect code; see following code
825bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  for (int i = 0; i < RD->getNumMembers(); i++) {
826bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    if (!RD->getMember(i)->getType()->isPointerType()) {
827bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
828bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
829bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
830bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
8316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
832bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This is a complete hack; we should be properly propagating
833bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // transparent_union through Sema.  That said, this is close enough to
834bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // correctly compile all the common cases of transparent_union without
835bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // errors or warnings
836bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  QualType NewTy = S.Context.VoidPtrTy;
837bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  NewTy.addConst();
838bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TD->setUnderlyingType(NewTy);
8396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
843545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
8440b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
8450b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           std::string("1"));
8466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
848545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
8496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
8506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
8526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
8536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
8540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
8556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
8586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                                          SE->getByteLength())));
8596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
861803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
863545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
864803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
865803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
8666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
870545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
8716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
8726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // (For now we just use 128 bits which is the maximum on X86.
8736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
8746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
87649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner
87749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
87849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
879803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
880803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
881803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "aligned", alignmentExpr->getSourceRange());
88249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
88349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
88449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
8856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
886fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
8870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with
888065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type.
889fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
890fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute,
891fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
892fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer.
893fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
8940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
895fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
896fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
897fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
898fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
899fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
9000b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
9010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           std::string("0"));
902fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
903fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
904fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
905fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
906fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
9070b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
908fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
909fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
910fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  const char *Str = Name->getName();
911fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned Len = Name->getLength();
912fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
913fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
914fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
915fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
916fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Str += 2;
917fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Len -= 4;
918fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
919fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
920fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
921fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
922fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (Len) {
923fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
924fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
925fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
926fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
927fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
928fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
929fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
930fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
931fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
932fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
933fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
934fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
935fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
936fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
937fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "word", 4))
9380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
939fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "byte", 4))
9400b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
941fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
942fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
943fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "pointer", 7))
9440b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
945fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
946fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
947fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
948fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
949fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
950fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
951fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
952fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
953fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
9540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode",
9550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           SourceRange(Attr.getLoc(), Attr.getLoc()));
956fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
957fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
958fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
959fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // FIXME: Need proper fixed-width types
960fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
961fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
962fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
9630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
964fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
965fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
9660b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
967fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
968fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
969fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
970fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
9710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
972fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
9730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
974fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
975fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
976fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
977fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
9780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
979fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
9800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
981fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
982fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
983fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
9840b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
985fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
9860b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
987fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
9880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
989fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
990fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
991fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
9920b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
993fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
9940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.LongLongTy;
995fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
9960b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedLongLongTy;
997fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
998fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
999fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1000fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!OldTy->getAsBuiltinType())
10010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1002fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (!(IntegerMode && OldTy->isIntegerType()) &&
1003fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner           !(!IntegerMode && OldTy->isFloatingType())) {
10040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1005fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1006fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1007fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
1008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1009fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    TD->setUnderlyingType(NewTy);
1010fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else
1011fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
1012fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
10130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
10140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
10150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
10160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
10170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1018803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
1019803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
1020803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it.
1021803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1022803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
10233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1024803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
1025803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
1026803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1027803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
10283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
10293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
10303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1031803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
10323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1033803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
10343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
10353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
10363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    HandleExtVectorTypeAttr(D, Attr, S);
10373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
1038803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1039803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
10403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1041eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
10423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
10433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
10443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
10453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
104673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
10473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
10483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
10493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
1050803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
1051803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
1052803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1053aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  case AttributeList::AT_objc_gc:     HandleObjCGCAttr    (D, Attr, S); break;
10549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1055803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
1056803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0
1057803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // TODO: when we have the full set of attributes, warn about unknown ones.
1058803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr->getLoc(), diag::warn_attribute_ignored,
1059803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           Attr->getName()->getName());
1060803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif
1061803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1062803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1063803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1064803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1065803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1066803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
1067803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1068803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  while (AttrList) {
1069803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    ProcessDeclAttribute(D, *AttrList, *this);
1070803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    AttrList = AttrList->getNext();
1071803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1072803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1073803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1074803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
10750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
10760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
10770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
10780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
10790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
10800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
10810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
1082803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
10830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
10840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
10850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
10860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
10870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
10880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
10890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner      ProcessDeclAttributeList(D, Attrs);
10900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
10910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
10920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
10930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
10940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
10950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1096