SemaDeclAttr.cpp revision 73798892751e378cbcdef43579c1d41685091fd0
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"
176e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek#include <llvm/ADT/StringExtras.h>
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) {
270eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
2716e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek             "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange());
272eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
273eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
274465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek
275465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
276eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
277eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
278eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (!proto->getArgType(x).getCanonicalType()->isPointerType()) {
279eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
280eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only,
281eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek             "nonnull", Ex->getSourceRange());
282eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
283eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
284eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
285eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
286eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
287eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
288eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  if (!NonNullArgs.empty()) {
289eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned* start = &NonNullArgs[0];
290eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned size = NonNullArgs.size();
291eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    std::sort(start, start + size);
292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    d->addAttr(new NonNullAttr(start, size));
293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  else
295eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    d->addAttr(new NonNullAttr());
296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
298803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
300545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
301803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
302803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
3036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
306545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
3076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
3086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
3096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
311803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
312803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "alias", std::string("1"));
3136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *Alias = Str->getStrData();
3176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned AliasLen = Str->getByteLength();
3186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
3206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
3226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
324803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
326545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
327803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
328803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
3296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
3336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Fn) {
334803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
335803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "noreturn", "function");
3366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoReturnAttr());
3406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
34273798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
34373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
34473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
34573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
34673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek           std::string("0"));
34773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
34873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
34973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
35073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  VarDecl *VD = dyn_cast<VarDecl>(d);
35173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
35273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (!VD) {
35373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
35473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek           "unused", "variable");
35573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
35673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
35773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
35873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  d->addAttr(new UnusedAttr());
35973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
36073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
361803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
363545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
364803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
365803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
3666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DeprecatedAttr());
3706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
372803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
374545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
375803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
376803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
3776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
380545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
3816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
3826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
3836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
385803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
386803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "visibility", std::string("1"));
3876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *TypeStr = Str->getStrData();
3916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned TypeLen = Str->getByteLength();
3926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  VisibilityAttr::VisibilityTypes type;
3936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
3956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::DefaultVisibility;
3966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
3976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility;
3986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
3996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility; // FIXME
4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
4016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::ProtectedVisibility;
4026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
403803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
404803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "visibility", TypeStr);
4056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new VisibilityAttr(type));
4096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
411803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
413545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
414803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
415803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new WeakAttr());
4206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
422803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
424545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
425803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
426803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLImportAttr());
4316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
433803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
435545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
436803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
437803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLExportAttr());
4426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
444803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
446545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
447803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
448803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new StdCallAttr());
4536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
455803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
457545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
458803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
459803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FastCallAttr());
4646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
466803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
468545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
469803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
470803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("0"));
4716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoThrowAttr());
4756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes
4786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
479803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
481545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
482803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
4836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("1"));
4846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
487545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
488803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
489803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("3"));
4906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // GCC ignores the format attribute on K&R style function
4946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // prototypes, so we ignore it as well
4956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const FunctionTypeProto *proto = getFunctionProto(d);
4966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!proto) {
498803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
499803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "format", "function");
5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: in C++ the implicit 'this' function parameter also counts.
5046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // this is needed in order to be compatible with GCC
5056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the index must start in 1 and the limit is numargs+1
5066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned NumArgs  = proto->getNumArgs();
5076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
5086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
509545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  const char *Format = Attr.getParameterName()->getName();
510545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  unsigned FormatLen = Attr.getParameterName()->getLength();
5116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
5136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
5146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
5156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Format += 2;
5166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    FormatLen -= 4;
5176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool Supported = false;
5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_NSString = false;
5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_strftime = false;
5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  switch (FormatLen) {
5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  default: break;
525803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 5: Supported = !memcmp(Format, "scanf", 5); break;
526803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 6: Supported = !memcmp(Format, "printf", 6); break;
527803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
5286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  case 8:
5296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                (is_NSString = !memcmp(Format, "NSString", 8));
5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    break;
5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Supported) {
535803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
536545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner           "format", Attr.getParameterName()->getName());
5376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
541545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
542803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
543803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
544803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
5456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("2"), IdxExpr->getSourceRange());
5466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
550803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
5516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("2"), IdxExpr->getSourceRange());
5526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
5566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
5576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
5596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty = proto->getArgType(ArgIdx);
5606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_NSString) {
5626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: do we need to check if the type is NSString*?  What are
5636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    //  the semantics?
564803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
5656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // FIXME: Should highlight the actual expression that has the
5666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // wrong type.
567803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString,
568803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner             IdxExpr->getSourceRange());
5696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
5706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
5716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
5726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
5736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: Should highlight the actual expression that has the
5746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // wrong type.
575803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string,
576803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           IdxExpr->getSourceRange());
5776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
581545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
582803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
583803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
584803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
5856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("3"), FirstArgExpr->getSourceRange());
5866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
5916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (proto->isVariadic()) {
5926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
5936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
594803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
5956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any variable
6006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the input is just the current time + the format string
6016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_strftime) {
6026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
603803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter,
6046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             FirstArgExpr->getSourceRange());
6056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
609803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
6106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner           "format", std::string("3"), FirstArgExpr->getSourceRange());
6116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
6156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                            Idx.getZExtValue(), FirstArg.getZExtValue()));
6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6180b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
6190b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
621545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
6220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
6236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         std::string("0"));
6246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  TypeDecl *decl = dyn_cast<TypeDecl>(d);
6286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6290b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner  if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) {
6300b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
6316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         "transparent_union", "union");
6326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  //QualType QTy = Context.getTypeDeclType(decl);
6366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  //const RecordType *Ty = QTy->getAsUnionType();
6376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// FIXME
6396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// Ty->addAttr(new TransparentUnionAttr());
6406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6420b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
644545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
6450b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
6460b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           std::string("1"));
6476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
649545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
6506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
6516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
6536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
6546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
6550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
6566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
6596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                                          SE->getByteLength())));
6606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
662803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
664545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
665803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
666803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           std::string("1"));
6676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
671545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
6736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // (For now we just use 128 bits which is the maximum on X86.
6746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
6756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
67749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner
67849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
67949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
680803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
681803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
682803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           "aligned", alignmentExpr->getSourceRange());
68349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
68449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
68549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
6866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
687fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
6880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with
689065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type.
690fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
691fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute,
692fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
693fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer.
694fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
6950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
696fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
700fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
7010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
7020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           std::string("0"));
703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
704fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
705fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
7080b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
710fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  const char *Str = Name->getName();
712fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned Len = Name->getLength();
713fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
714fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
715fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
716fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
717fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Str += 2;
718fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Len -= 4;
719fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
720fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
721fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
722fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
723fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (Len) {
724fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
725fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
726fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
727fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
728fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
729fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
730fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
731fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
732fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
733fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
734fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
735fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
736fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
737fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
738fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "word", 4))
7390b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
740fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "byte", 4))
7410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
743fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
744fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "pointer", 7))
7450b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
747fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
748fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
749fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
750fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
751fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
753fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
754fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
7550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode",
7560b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner           SourceRange(Attr.getLoc(), Attr.getLoc()));
757fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
758fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
760fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // FIXME: Need proper fixed-width types
761fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
762fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
763fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
7640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
765fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
7670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
770fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
771fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
7720b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
773fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
7740b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
775fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
776fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
777fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
7790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
780fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
7810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
783fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
784fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
7850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
786fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
7870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
788fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
7890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
790fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
791fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
792fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
7930b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
794fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
7950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.LongLongTy;
796fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
7970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedLongLongTy;
798fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
799fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
800fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
801fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!OldTy->getAsBuiltinType())
8020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
803fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (!(IntegerMode && OldTy->isIntegerType()) &&
804fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner           !(!IntegerMode && OldTy->isFloatingType())) {
8050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
806fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
807fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
808fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
809fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
810fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    TD->setUnderlyingType(NewTy);
811fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else
812fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
813fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
8140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
8150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
8160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
8170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
8180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
819803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
820803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
821803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it.
822803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
823803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
824803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
825803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
826803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
827803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_ext_vector_type:
828803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleExtVectorTypeAttr(D, Attr, S);
829803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
830803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
831803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
832803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
833803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
834803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
835803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
836803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
837803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
838803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
839803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
840803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
841803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
842803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
843803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
844803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
845803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
846eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
847eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
84873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
849803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
850803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
851803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
852803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
853803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0
854803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // TODO: when we have the full set of attributes, warn about unknown ones.
855803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr->getLoc(), diag::warn_attribute_ignored,
856803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner           Attr->getName()->getName());
857803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif
858803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
859803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
860803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
861803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
862803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
863803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
864803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
865803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  while (AttrList) {
866803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    ProcessDeclAttribute(D, *AttrList, *this);
867803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    AttrList = AttrList->getNext();
868803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
869803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
870803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
871803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
8720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
8730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
8740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
8750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
8760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
8770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
8780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
879803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
8800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
8810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
8820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
8830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
8840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
8850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
8860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner      ProcessDeclAttributeList(D, Attrs);
8870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
8880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
8890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
8900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
8910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
8920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
893