SemaDeclAttr.cpp revision 465172f304248a9aab6f2c398a836ce4e25efbbf
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"
16fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
17465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek#include <sstream>
186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
20e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
21e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
22e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
23e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic const FunctionTypeProto *getFunctionProto(Decl *d) {
256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = Ty->getAsPointerType()->getPointeeType();
376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (const FunctionType *FnTy = Ty->getAsFunctionType())
396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType());
406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return 0;
426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!T->isPointerType())
466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  T = T->getAsPointerType()->getPointeeType().getCanonicalType();
496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  ObjCInterfaceType* ClsT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!ClsT)
526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
61e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
62e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
63e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
64e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
65803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
66803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner                                    Sema &S) {
67545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
68545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
69803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
70545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
75545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
76803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
77803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
80545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
82803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
83803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
84803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "ext_vector_type", sizeExpr->getSourceRange());
856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // in conjunction with complex types (pointers, arrays, functions, etc.).
896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Type *canonType = curType.getCanonicalType().getTypePtr();
906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
91803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
92803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           curType.getCanonicalType().getAsString());
936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, the size is specified as the
966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // number of elements, not the number of bytes.
976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
100803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
101803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           sizeExpr->getSourceRange());
1026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Instantiate/Install the vector type, the number of elements is > 0.
105803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
1066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Remember this typedef decl, we will need it later for diagnostics.
107803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  S.ExtVectorDecls.push_back(tDecl);
1086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
110065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
111065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to
112065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function
113065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates
114065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a
115065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar.
116065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size
117065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well
118065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type.
119803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
120065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  QualType CurType;
121065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
122065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = VD->getType();
123065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
124065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = TD->getUnderlyingType();
125065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else {
126803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl,
127803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("vector_size"),
128803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           SourceRange(Attr.getLoc(), Attr.getLoc()));
129065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
130065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  }
131065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
132065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Check the attribute arugments.
133545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
134803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
135803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
136065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
138545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
1396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
140803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
141803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
142803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "vector_size", sizeExpr->getSourceRange());
143065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // navigate to the base type - we need to provide for vector pointers,
1466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vector arrays, and functions returning vectors.
147065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  Type *canonType = CurType.getCanonicalType().getTypePtr();
1486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (canonType->isPointerType() || canonType->isArrayType() ||
1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      canonType->isFunctionType()) {
1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    assert(0 && "HandleVector(): Complex type construction unimplemented");
1526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
1536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     do {
1546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     if (PointerType *PT = dyn_cast<PointerType>(canonType))
1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = PT->getPointeeType().getTypePtr();
1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = AT->getElementType().getTypePtr();
1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
1596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = FT->getResultType().getTypePtr();
1606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     } while (canonType->isPointerType() || canonType->isArrayType() ||
1616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType->isFunctionType());
1626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     */
1636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the base type must be integer or float.
1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
166803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
167803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           CurType.getCanonicalType().getAsString());
168065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
170803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
1716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vecSize is specified in bytes - convert to bits.
1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the vector size needs to be an integral multiple of the type size.
1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize % typeSize) {
176803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size,
177803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           sizeExpr->getSourceRange());
178065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
181803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
182803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           sizeExpr->getSourceRange());
183065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
1846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
185065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
186065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Success! Instantiate the vector type, the number of elements is > 0, and
187065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // not required to be a power of 2, unlike GCC.
188803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
189065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
190065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
191065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    VD->setType(CurType);
192065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else
193065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    cast<TypedefDecl>(D)->setUnderlyingType(CurType);
1946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
196803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
198545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
199803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
200803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
2016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
20549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    TD->addAttr(new PackedAttr());
2066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
210803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
211803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(Attr.getLoc(),
212803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner             diag::warn_attribute_ignored_for_field_of_type,
213803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner             Attr.getName()->getName(), FD->getType().getAsString());
2146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
21549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner      FD->addAttr(new PackedAttr());
2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
217803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored,
218803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           Attr.getName()->getName());
2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
22196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
22296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
22396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
22496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
22596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek           std::string("0"));
22696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
22796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
22896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
22996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // The IBOutlet attribute only applies to instance variables of Objective-C
23096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // classes.
23196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d))
23296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    ID->addAttr(new IBOutletAttr());
23396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  else
23496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar);
23596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
23696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
237eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
238eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
239eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // GCC ignores the nonnull attribute on K&R style function
240eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // prototypes, so we ignore it as well
241eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  const FunctionTypeProto *proto = getFunctionProto(d);
242eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
243eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  if (!proto) {
244eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
245eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek           "nonnull", "function");
246eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
247eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
248eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
249eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  unsigned NumArgs = proto->getNumArgs();
250eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
251eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
252eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
253eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
254eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
255eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
256eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
257eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
258eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
259eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    Expr *Ex = static_cast<Expr *>(Attr.getArg(0));
260eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
261eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
262eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
263eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek             "nonnull", Ex->getSourceRange());
264eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
265eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
266eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
267eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
268eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
269eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
270465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek      std::ostringstream os;
271465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek      os << I.getArgNum();
272eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
273465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek             "nonnull", os.str(), Ex->getSourceRange());
274eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
275eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
276465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek
277465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
278eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
279eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
280eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (!proto->getArgType(x).getCanonicalType()->isPointerType()) {
281eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
282eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only,
283eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek             "nonnull", Ex->getSourceRange());
284eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
285eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
286eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
287eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
288eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
289eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
290eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  if (!NonNullArgs.empty()) {
291eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned* start = &NonNullArgs[0];
292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned size = NonNullArgs.size();
293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    std::sort(start, start + size);
294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    d->addAttr(new NonNullAttr(start, size));
295eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  else
297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    d->addAttr(new NonNullAttr());
298eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
299eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
300803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
302545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
303803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
304803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
3056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
308545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
3096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
3106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
3116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
313803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
314803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "alias", std::string("1"));
3156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *Alias = Str->getStrData();
3196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned AliasLen = Str->getByteLength();
3206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
3226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
3246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
326803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
328545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
329803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
330803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
3316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
3356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Fn) {
336803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
337803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "noreturn", "function");
3386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoReturnAttr());
3426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
344803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
346545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
347803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
348803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
3496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DeprecatedAttr());
3536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
355803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
357545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
358803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
359803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
3606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
363545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
3646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
3656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
3666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
368803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
369803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "visibility", std::string("1"));
3706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *TypeStr = Str->getStrData();
3746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned TypeLen = Str->getByteLength();
3756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  VisibilityAttr::VisibilityTypes type;
3766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
3786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::DefaultVisibility;
3796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
3806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility;
3816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
3826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility; // FIXME
3836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::ProtectedVisibility;
3856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
386803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
387803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "visibility", TypeStr);
3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new VisibilityAttr(type));
3926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
394803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
396545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
397803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
398803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
3996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new WeakAttr());
4036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
405803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
407545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
408803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
409803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLImportAttr());
4146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
416803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
418545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
419803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
420803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLExportAttr());
4256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
427803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
429545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
430803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
431803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new StdCallAttr());
4366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
438803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
440545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
441803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
442803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FastCallAttr());
4476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
449803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
451545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
452803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
453803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoThrowAttr());
4586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes
4616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
462803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
464545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
465803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
4666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("1"));
4676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
470545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
471803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
472803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("3"));
4736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // GCC ignores the format attribute on K&R style function
4776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // prototypes, so we ignore it as well
4786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const FunctionTypeProto *proto = getFunctionProto(d);
4796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!proto) {
481803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
482803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "format", "function");
4836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: in C++ the implicit 'this' function parameter also counts.
4876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // this is needed in order to be compatible with GCC
4886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the index must start in 1 and the limit is numargs+1
4896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned NumArgs  = proto->getNumArgs();
4906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
4916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
492545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  const char *Format = Attr.getParameterName()->getName();
493545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  unsigned FormatLen = Attr.getParameterName()->getLength();
4946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
4966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
4986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Format += 2;
4996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    FormatLen -= 4;
5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool Supported = false;
5036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_NSString = false;
5046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_strftime = false;
5056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  switch (FormatLen) {
5076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  default: break;
508803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 5: Supported = !memcmp(Format, "scanf", 5); break;
509803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 6: Supported = !memcmp(Format, "printf", 6); break;
510803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
5116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  case 8:
5126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
5136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                (is_NSString = !memcmp(Format, "NSString", 8));
5146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    break;
5156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Supported) {
518803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
519545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner           "format", Attr.getParameterName()->getName());
5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
524545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
525803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
526803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
527803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
5286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("2"), IdxExpr->getSourceRange());
5296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
533803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("2"), IdxExpr->getSourceRange());
5356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
5406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
5426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty = proto->getArgType(ArgIdx);
5436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_NSString) {
5456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: do we need to check if the type is NSString*?  What are
5466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    //  the semantics?
547803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
5486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // FIXME: Should highlight the actual expression that has the
5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // wrong type.
550803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString,
551803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner             IdxExpr->getSourceRange());
5526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
5536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
5556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
5566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: Should highlight the actual expression that has the
5576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // wrong type.
558803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string,
559803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           IdxExpr->getSourceRange());
5606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
564545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
565803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
566803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
567803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
5686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("3"), FirstArgExpr->getSourceRange());
5696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
5736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
5746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (proto->isVariadic()) {
5756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
5766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
577803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
5786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
5806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any variable
5836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the input is just the current time + the format string
5846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_strftime) {
5856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
586803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter,
5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             FirstArgExpr->getSourceRange());
5886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
5896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
5916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
592803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
5936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("3"), FirstArgExpr->getSourceRange());
5946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
5986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                            Idx.getZExtValue(), FirstArg.getZExtValue()));
5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
6020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
6036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
604545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
6050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         std::string("0"));
6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  TypeDecl *decl = dyn_cast<TypeDecl>(d);
6116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6120b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner  if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) {
6130b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
6146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         "transparent_union", "union");
6156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  //QualType QTy = Context.getTypeDeclType(decl);
6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  //const RecordType *Ty = QTy->getAsUnionType();
6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// FIXME
6226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// Ty->addAttr(new TransparentUnionAttr());
6236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6250b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
627545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
6280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
6290b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           std::string("1"));
6306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
632545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
6336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
6346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
6366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
6376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
6380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
6396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
6426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                                          SE->getByteLength())));
6436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
645803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
647545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
648803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
649803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
6506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
654545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
6556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
6566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // (For now we just use 128 bits which is the maximum on X86.
6576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
6586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
66049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner
66149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
66249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
663803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
664803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
665803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "aligned", alignmentExpr->getSourceRange());
66649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
66749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
66849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
670fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
6710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with
672065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type.
673fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute,
675fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
676fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer.
677fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
6780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
679fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
680fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
681fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
682fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
683fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
6840b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
6850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           std::string("0"));
686fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
687fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
688fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
689fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
690fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
6910b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
692fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
693fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
694fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  const char *Str = Name->getName();
695fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned Len = Name->getLength();
696fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
700fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Str += 2;
701fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Len -= 4;
702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
704fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
705fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (Len) {
707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
708fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
710fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
712fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
713fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
714fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
715fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
716fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
717fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
718fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
719fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
720fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
721fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "word", 4))
7220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
723fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "byte", 4))
7240b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
725fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
726fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
727fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "pointer", 7))
7280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
729fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
730fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
731fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
732fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
733fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
734fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
735fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
736fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
737fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
7380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode",
7390b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           SourceRange(Attr.getLoc(), Attr.getLoc()));
740fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
741fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
743fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // FIXME: Need proper fixed-width types
744fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
745fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
7470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
748fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
749fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
7500b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
751fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
753fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
754fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
7550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
756fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
7570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
758fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
760fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
761fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
7620b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
763fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
7640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
765fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
767fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
7680b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
7700b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
771fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
7720b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
773fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
775fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
7760b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
777fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
7780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.LongLongTy;
779fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
7800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedLongLongTy;
781fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
783fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
784fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!OldTy->getAsBuiltinType())
7850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
786fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (!(IntegerMode && OldTy->isIntegerType()) &&
787fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner           !(!IntegerMode && OldTy->isFloatingType())) {
7880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
789fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
790fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
791fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
792fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
793fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    TD->setUnderlyingType(NewTy);
794fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else
795fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
796fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
7970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
7980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
7990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
8000744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
8010744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
802803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
803803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
804803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it.
805803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
806803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
807803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
808803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
809803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
810803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_ext_vector_type:
811803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleExtVectorTypeAttr(D, Attr, S);
812803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
813803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
814803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
815803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
816803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
817803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
818803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
819803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
820803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
821803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
822803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
823803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
824803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
825803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
826803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
827803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
828803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
829eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
830eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
831803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
832803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
833803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
834803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
835803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0
836803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // TODO: when we have the full set of attributes, warn about unknown ones.
837803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr->getLoc(), diag::warn_attribute_ignored,
838803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           Attr->getName()->getName());
839803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif
840803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
841803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
842803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
843803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
844803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
845803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
846803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
847803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  while (AttrList) {
848803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    ProcessDeclAttribute(D, *AttrList, *this);
849803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    AttrList = AttrList->getNext();
850803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
851803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
852803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
853803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
8540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
8550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
8560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
8570744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
8580744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
8590744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
8600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
861803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
8620744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
8630744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
8640744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
8650744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
8660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
8670744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
8680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner      ProcessDeclAttributeList(D, Attrs);
8690744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
8700744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
8710744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
8720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
8730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
8740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
875