diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj
index 17d0042..bb9935a 100644
--- a/clang.xcodeproj/project.pbxproj
+++ b/clang.xcodeproj/project.pbxproj
@@ -62,6 +62,7 @@
 		DE224FF80C7AA98800D370A5 /* CGExprComplex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */; };
 		DE2252700C7E82D000D370A5 /* CGExprScalar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */; };
 		DE2255FC0C8004E600D370A5 /* ParseDeclCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */; };
+		DE22BCF20E14197E0094DC60 /* SemaDeclAttr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */; };
 		DE344AB80AE5DF6D00DBC861 /* HeaderSearch.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */; };
 		DE344B540AE5E46C00DBC861 /* HeaderSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */; };
 		DE3450D70AEB543100DBC861 /* DirectoryLookup.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3450D60AEB543100DBC861 /* DirectoryLookup.h */; };
@@ -346,6 +347,7 @@
 		DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprComplex.cpp; path = lib/CodeGen/CGExprComplex.cpp; sourceTree = "<group>"; };
 		DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprScalar.cpp; path = lib/CodeGen/CGExprScalar.cpp; sourceTree = "<group>"; };
 		DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseDeclCXX.cpp; path = lib/Parse/ParseDeclCXX.cpp; sourceTree = "<group>"; };
+		DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclAttr.cpp; path = lib/Sema/SemaDeclAttr.cpp; sourceTree = "<group>"; };
 		DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HeaderSearch.h; sourceTree = "<group>"; };
 		DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HeaderSearch.cpp; sourceTree = "<group>"; };
 		DE3450D60AEB543100DBC861 /* DirectoryLookup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DirectoryLookup.h; sourceTree = "<group>"; };
@@ -688,6 +690,7 @@
 				DE67E7160C020EE400F66BC5 /* Sema.cpp */,
 				DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */,
 				DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */,
+				DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */,
 				35EF676F0DAD1D2C00B19414 /* SemaDeclCXX.cpp */,
 				DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */,
 				DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */,
@@ -1111,6 +1114,7 @@
 				35EE48B10E0C4CCA00715C54 /* DeclCXX.cpp in Sources */,
 				35EE48B20E0C4CCA00715C54 /* ParentMap.cpp in Sources */,
 				3534A01D0E129849002709B2 /* ParseCXXInlineMethods.cpp in Sources */,
+				DE22BCF20E14197E0094DC60 /* SemaDeclAttr.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index b954c8b..0b048b0 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -19,13 +19,13 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/Type.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/SourceManager.h"
-#include "clang/AST/ExprCXX.h"
 // FIXME: layering (ideally, Sema shouldn't be dependent on Lex API's)
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/HeaderSearch.h" 
@@ -260,7 +260,8 @@
   return New;
 }
 
-/// DeclhasAttr - returns true if decl Declaration already has the target attribute.
+/// DeclhasAttr - returns true if decl Declaration already has the target
+/// attribute.
 static bool DeclHasAttr(const Decl *decl, const Attr *target) {
   for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
     if (attr->getKind() == target->getKind())
@@ -2325,673 +2326,3 @@
   // FIXME: Add all the various semantics of linkage specifications
   return LinkageSpecDecl::Create(Context, Loc, Language, dcl);
 }
-
-void Sema::HandleDeclAttribute(Decl *New, const AttributeList *Attr) {
-  
-  switch (Attr->getKind()) {
-  case AttributeList::AT_vector_size:
-    if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
-      QualType newType = HandleVectorTypeAttribute(vDecl->getType(), Attr);
-      if (!newType.isNull()) // install the new vector type into the decl
-        vDecl->setType(newType);
-    } 
-    if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
-      QualType newType = HandleVectorTypeAttribute(tDecl->getUnderlyingType(), 
-                                                   Attr);
-      if (!newType.isNull()) // install the new vector type into the decl
-        tDecl->setUnderlyingType(newType);
-    }
-    break;
-  case AttributeList::AT_ext_vector_type:
-    if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New))
-      HandleExtVectorTypeAttribute(tDecl, Attr);
-    else
-      Diag(Attr->getLoc(), 
-           diag::err_typecheck_ext_vector_not_typedef);
-    break;
-  case AttributeList::AT_address_space:
-    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
-    break;
-  case AttributeList::AT_mode:
-    // Despite what would be logical, the mode attribute is a decl attribute,
-    // not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
-    // 'G' be HImode, not an intermediate pointer.
-    if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
-      QualType newType = HandleModeTypeAttribute(tDecl->getUnderlyingType(),
-                                                 Attr);
-      tDecl->setUnderlyingType(newType);
-    } else if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
-      QualType newType = HandleModeTypeAttribute(vDecl->getType(), Attr);
-      vDecl->setType(newType);
-    }
-    // FIXME: Diagnostic?
-    break;
-  case AttributeList::AT_alias:
-    HandleAliasAttribute(New, Attr);
-    break;
-  case AttributeList::AT_deprecated:
-    HandleDeprecatedAttribute(New, Attr);
-    break;
-  case AttributeList::AT_visibility:
-    HandleVisibilityAttribute(New, Attr);
-    break;
-  case AttributeList::AT_weak:
-    HandleWeakAttribute(New, Attr);
-    break;
-  case AttributeList::AT_dllimport:
-    HandleDLLImportAttribute(New, Attr);
-    break;
-  case AttributeList::AT_dllexport:
-    HandleDLLExportAttribute(New, Attr);
-    break;
-  case AttributeList::AT_nothrow:
-    HandleNothrowAttribute(New, Attr);
-    break;
-  case AttributeList::AT_stdcall:
-    HandleStdCallAttribute(New, Attr);
-    break;
-  case AttributeList::AT_fastcall:
-    HandleFastCallAttribute(New, Attr);
-    break;
-  case AttributeList::AT_aligned:
-    HandleAlignedAttribute(New, Attr);
-    break;
-  case AttributeList::AT_packed:
-    HandlePackedAttribute(New, Attr);
-    break;
-  case AttributeList::AT_annotate:
-    HandleAnnotateAttribute(New, Attr);
-    break;
-  case AttributeList::AT_noreturn:
-    HandleNoReturnAttribute(New, Attr);
-    break;
-  case AttributeList::AT_format:
-    HandleFormatAttribute(New, Attr);
-    break;
-  case AttributeList::AT_transparent_union:
-    HandleTransparentUnionAttribute(New, Attr);
-    break;
-  default:
-#if 0
-    // TODO: when we have the full set of attributes, warn about unknown ones.
-    Diag(Attr->getLoc(), diag::warn_attribute_ignored,
-         Attr->getName()->getName());
-#endif
-    break;
-  }
-}
-
-void Sema::HandleDeclAttributes(Decl *New, const AttributeList *DeclSpecAttrs,
-                                const AttributeList *DeclaratorAttrs) {
-  if (DeclSpecAttrs == 0 && DeclaratorAttrs == 0) return;
-  
-  while (DeclSpecAttrs) {
-    HandleDeclAttribute(New, DeclSpecAttrs);
-    DeclSpecAttrs = DeclSpecAttrs->getNext();
-  }
-  
-  // If there are any type attributes that were in the declarator, apply them to
-  // its top level type.
-  if (ValueDecl *VD = dyn_cast<ValueDecl>(New)) {
-    QualType DT = VD->getType();
-    ProcessTypeAttributes(DT, DeclaratorAttrs);
-    VD->setType(DT);
-  } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(New)) {
-    QualType DT = TD->getUnderlyingType();
-    ProcessTypeAttributes(DT, DeclaratorAttrs);
-    TD->setUnderlyingType(DT);
-  }
-  
-  while (DeclaratorAttrs) {
-    HandleDeclAttribute(New, DeclaratorAttrs);
-    DeclaratorAttrs = DeclaratorAttrs->getNext();
-  }
-}
-
-void Sema::HandleExtVectorTypeAttribute(TypedefDecl *tDecl, 
-                                        const AttributeList *rawAttr) {
-  QualType curType = tDecl->getUnderlyingType();
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 1) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("1"));
-    return;
-  }
-  Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
-  llvm::APSInt vecSize(32);
-  if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
-         "ext_vector_type", sizeExpr->getSourceRange());
-    return;
-  }
-  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
-  // in conjunction with complex types (pointers, arrays, functions, etc.).
-  Type *canonType = curType.getCanonicalType().getTypePtr();
-  if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_invalid_vector_type,
-         curType.getCanonicalType().getAsString());
-    return;
-  }
-  // unlike gcc's vector_size attribute, the size is specified as the 
-  // number of elements, not the number of bytes.
-  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 
-  
-  if (vectorSize == 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_zero_size,
-         sizeExpr->getSourceRange());
-    return;
-  }
-  // Instantiate/Install the vector type, the number of elements is > 0.
-  tDecl->setUnderlyingType(Context.getExtVectorType(curType, vectorSize));
-  // Remember this typedef decl, we will need it later for diagnostics.
-  ExtVectorDecls.push_back(tDecl);
-}
-
-QualType Sema::HandleVectorTypeAttribute(QualType curType, 
-                                         const AttributeList *rawAttr) {
-  // check the attribute arugments.
-  if (rawAttr->getNumArgs() != 1) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("1"));
-    return QualType();
-  }
-  Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
-  llvm::APSInt vecSize(32);
-  if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
-         "vector_size", sizeExpr->getSourceRange());
-    return QualType();
-  }
-  // navigate to the base type - we need to provide for vector pointers, 
-  // vector arrays, and functions returning vectors.
-  Type *canonType = curType.getCanonicalType().getTypePtr();
-  
-  if (canonType->isPointerType() || canonType->isArrayType() ||
-      canonType->isFunctionType()) {
-    assert(0 && "HandleVector(): Complex type construction unimplemented");
-    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
-        do {
-          if (PointerType *PT = dyn_cast<PointerType>(canonType))
-            canonType = PT->getPointeeType().getTypePtr();
-          else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
-            canonType = AT->getElementType().getTypePtr();
-          else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
-            canonType = FT->getResultType().getTypePtr();
-        } while (canonType->isPointerType() || canonType->isArrayType() ||
-                 canonType->isFunctionType());
-    */
-  }
-  // the base type must be integer or float.
-  if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_invalid_vector_type,
-         curType.getCanonicalType().getAsString());
-    return QualType();
-  }
-  unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(curType));
-  // vecSize is specified in bytes - convert to bits.
-  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 
-  
-  // the vector size needs to be an integral multiple of the type size.
-  if (vectorSize % typeSize) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_invalid_size,
-         sizeExpr->getSourceRange());
-    return QualType();
-  }
-  if (vectorSize == 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_zero_size,
-         sizeExpr->getSourceRange());
-    return QualType();
-  }
-  // Instantiate the vector type, the number of elements is > 0, and not
-  // required to be a power of 2, unlike GCC.
-  return Context.getVectorType(curType, vectorSize/typeSize);
-}
-
-void Sema::HandlePackedAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() > 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return;
-  }
-  
-  if (TagDecl *TD = dyn_cast<TagDecl>(d))
-    TD->addAttr(new PackedAttr);
-  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
-    // If the alignment is less than or equal to 8 bits, the packed attribute
-    // has no effect.
-    if (!FD->getType()->isIncompleteType() &&
-        Context.getTypeAlign(FD->getType()) <= 8)
-      Diag(rawAttr->getLoc(), 
-           diag::warn_attribute_ignored_for_field_of_type,
-           rawAttr->getName()->getName(), FD->getType().getAsString());
-    else
-      FD->addAttr(new PackedAttr);
-  } else
-    Diag(rawAttr->getLoc(), diag::warn_attribute_ignored,
-         rawAttr->getName()->getName());
-}
-
-void Sema::HandleAliasAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 1) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("1"));
-    return;
-  }
-
-  Expr *Arg = static_cast<Expr*>(rawAttr->getArg(0));
-  Arg = Arg->IgnoreParenCasts();
-  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
-
-  if (Str == 0 || Str->isWide()) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
-         "alias", std::string("1"));
-    return;
-  }
-
-  const char *Alias = Str->getStrData();
-  unsigned AliasLen = Str->getByteLength();
-
-  // FIXME: check if target symbol exists in current file
-
-  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
-}
-
-void Sema::HandleNoReturnAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return;
-  }
-  
-  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
-  
-  if (!Fn) {
-    Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
-         "noreturn", "function");
-    return;
-  }
-  
-  d->addAttr(new NoReturnAttr());
-}
-
-void Sema::HandleDeprecatedAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return;
-  }
-
-  d->addAttr(new DeprecatedAttr());
-}
-
-void Sema::HandleVisibilityAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 1) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("1"));
-    return;
-  }
-
-  Expr *Arg = static_cast<Expr*>(rawAttr->getArg(0));
-  Arg = Arg->IgnoreParenCasts();
-  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
-  
-  if (Str == 0 || Str->isWide()) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
-         "visibility", std::string("1"));
-    return;
-  }
-
-  const char *TypeStr = Str->getStrData();
-  unsigned TypeLen = Str->getByteLength();
-  VisibilityAttr::VisibilityTypes type;
-
-  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
-    type = VisibilityAttr::DefaultVisibility;
-  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
-    type = VisibilityAttr::HiddenVisibility;
-  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
-    type = VisibilityAttr::HiddenVisibility; // FIXME
-  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
-    type = VisibilityAttr::ProtectedVisibility;
-  else {
-    Diag(rawAttr->getLoc(), diag::warn_attribute_type_not_supported,
-           "visibility", TypeStr);
-    return;
-  }
-
-  d->addAttr(new VisibilityAttr(type));
-}
-
-void Sema::HandleWeakAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return;
-  }
-
-  d->addAttr(new WeakAttr());
-}
-
-void Sema::HandleDLLImportAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return;
-  }
-
-  d->addAttr(new DLLImportAttr());
-}
-
-void Sema::HandleDLLExportAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return;
-  }
-
-  d->addAttr(new DLLExportAttr());
-}
-
-void Sema::HandleStdCallAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return;
-  }
-
-  d->addAttr(new StdCallAttr());
-}
-
-void Sema::HandleFastCallAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return;
-  }
-
-  d->addAttr(new FastCallAttr());
-}
-
-void Sema::HandleNothrowAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return;
-  }
-
-  d->addAttr(new NoThrowAttr());
-}
-
-static const FunctionTypeProto *getFunctionProto(Decl *d) {
-  QualType Ty;
-
-  if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
-    Ty = decl->getType();
-  else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
-    Ty = decl->getType();
-  else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
-    Ty = decl->getUnderlyingType();
-  else
-    return 0;
-
-  if (Ty->isFunctionPointerType()) {
-    const PointerType *PtrTy = Ty->getAsPointerType();
-    Ty = PtrTy->getPointeeType();
-  }
-
-  if (const FunctionType *FnTy = Ty->getAsFunctionType())
-    return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType());
-
-  return 0;
-}
-
-static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
-  if (!T->isPointerType())
-    return false;
-  
-  T = T->getAsPointerType()->getPointeeType().getCanonicalType();
-  ObjCInterfaceType* ClsT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
-  
-  if (!ClsT)
-    return false;
-  
-  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
-  
-  // FIXME: Should we walk the chain of classes?
-  return ClsName == &Ctx.Idents.get("NSString") ||
-         ClsName == &Ctx.Idents.get("NSMutableString");
-}
-
-/// Handle __attribute__((format(type,idx,firstarg))) attributes
-/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
-void Sema::HandleFormatAttribute(Decl *d, const AttributeList *rawAttr) {
-
-  if (!rawAttr->getParameterName()) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
-           "format", std::string("1"));
-    return;
-  }
-
-  if (rawAttr->getNumArgs() != 2) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("3"));
-    return;
-  }
-
-  // GCC ignores the format attribute on K&R style function
-  // prototypes, so we ignore it as well
-  const FunctionTypeProto *proto = getFunctionProto(d);
-
-  if (!proto) {
-    Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
-           "format", "function");
-    return;
-  }
-
-  // FIXME: in C++ the implicit 'this' function parameter also counts.
-  // this is needed in order to be compatible with GCC
-  // the index must start in 1 and the limit is numargs+1
-  unsigned NumArgs  = proto->getNumArgs();
-  unsigned FirstIdx = 1;
-
-  const char *Format = rawAttr->getParameterName()->getName();
-  unsigned FormatLen = rawAttr->getParameterName()->getLength();
-
-  // Normalize the argument, __foo__ becomes foo.
-  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
-      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
-    Format += 2;
-    FormatLen -= 4;
-  }
-
-  bool Supported = false;
-  bool is_NSString = false;
-  bool is_strftime = false;
-  
-  switch (FormatLen) {
-    default: break;
-    case 5:
-      Supported = !memcmp(Format, "scanf", 5);
-      break;
-    case 6:
-      Supported = !memcmp(Format, "printf", 6);
-      break;
-    case 7:
-      Supported = !memcmp(Format, "strfmon", 7);
-      break;
-    case 8:
-      Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 
-                  (is_NSString = !memcmp(Format, "NSString", 8));
-      break;
-  }
-      
-  if (!Supported) {
-    Diag(rawAttr->getLoc(), diag::warn_attribute_type_not_supported,
-           "format", rawAttr->getParameterName()->getName());
-    return;
-  }
-
-  // checks for the 2nd argument
-  Expr *IdxExpr = static_cast<Expr *>(rawAttr->getArg(0));
-  llvm::APSInt Idx(Context.getTypeSize(IdxExpr->getType()));
-  if (!IdxExpr->isIntegerConstantExpr(Idx, Context)) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int,
-           "format", std::string("2"), IdxExpr->getSourceRange());
-    return;
-  }
-
-  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_argument_out_of_bounds,
-           "format", std::string("2"), IdxExpr->getSourceRange());
-    return;
-  }
-
-  // FIXME: Do we need to bounds check?
-  unsigned ArgIdx = Idx.getZExtValue() - 1;
-  
-  // make sure the format string is really a string
-  QualType Ty = proto->getArgType(ArgIdx);
-
-  if (is_NSString) {
-    // FIXME: do we need to check if the type is NSString*?  What are
-    //  the semantics?
-    if (!isNSStringType(Ty, Context)) {
-      // FIXME: Should highlight the actual expression that has the
-      // wrong type.
-      Diag(rawAttr->getLoc(), diag::err_format_attribute_not_NSString,
-           IdxExpr->getSourceRange());
-      return;
-    }    
-  }
-  else if (!Ty->isPointerType() ||
-      !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
-    // FIXME: Should highlight the actual expression that has the
-    // wrong type.
-    Diag(rawAttr->getLoc(), diag::err_format_attribute_not_string,
-         IdxExpr->getSourceRange());
-    return;
-  }
-
-  // check the 3rd argument
-  Expr *FirstArgExpr = static_cast<Expr *>(rawAttr->getArg(1));
-  llvm::APSInt FirstArg(Context.getTypeSize(FirstArgExpr->getType()));
-  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, Context)) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int,
-           "format", std::string("3"), FirstArgExpr->getSourceRange());
-    return;
-  }
-
-  // check if the function is variadic if the 3rd argument non-zero
-  if (FirstArg != 0) {
-    if (proto->isVariadic()) {
-      ++NumArgs; // +1 for ...
-    } else {
-      Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
-      return;
-    }
-  }
-
-  // strftime requires FirstArg to be 0 because it doesn't read from any variable
-  // the input is just the current time + the format string
-  if (is_strftime) {
-    if (FirstArg != 0) {
-      Diag(rawAttr->getLoc(), diag::err_format_strftime_third_parameter,
-             FirstArgExpr->getSourceRange());
-      return;
-    }
-  // if 0 it disables parameter checking (to use with e.g. va_list)
-  } else if (FirstArg != 0 && FirstArg != NumArgs) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_argument_out_of_bounds,
-           "format", std::string("3"), FirstArgExpr->getSourceRange());
-    return;
-  }
-
-  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
-                            Idx.getZExtValue(), FirstArg.getZExtValue()));
-}
-
-void Sema::HandleTransparentUnionAttribute(Decl *d,
-                                           const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 0) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return;
-  }
-
-  TypeDecl *decl = dyn_cast<TypeDecl>(d);
-
-  if (!decl || !Context.getTypeDeclType(decl)->isUnionType()) {
-    Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
-         "transparent_union", "union");
-    return;
-  }
-
-  //QualType QTy = Context.getTypeDeclType(decl);
-  //const RecordType *Ty = QTy->getAsUnionType();
-
-// FIXME
-// Ty->addAttr(new TransparentUnionAttr());
-}
-
-void Sema::HandleAnnotateAttribute(Decl *d, const AttributeList *rawAttr) {
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() != 1) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("1"));
-    return;
-  }
-  Expr *argExpr = static_cast<Expr *>(rawAttr->getArg(0));
-  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
-  
-  // Make sure that there is a string literal as the annotation's single
-  // argument.
-  if (!SE) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_annotate_no_string);
-    return;
-  }
-  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
-                                          SE->getByteLength())));
-}
-
-void Sema::HandleAlignedAttribute(Decl *d, const AttributeList *rawAttr)
-{
-  // check the attribute arguments.
-  if (rawAttr->getNumArgs() > 1) {
-    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("1"));
-    return;
-  }
-
-  unsigned Align = 0;
-  
-  if (rawAttr->getNumArgs() == 0) {
-    // FIXME: This should be the target specific maximum alignment.
-    // (For now we just use 128 bits which is the maximum on X86.
-    Align = 128;
-    return;
-  } else {
-    Expr *alignmentExpr = static_cast<Expr *>(rawAttr->getArg(0));
-    llvm::APSInt alignment(32);
-    if (!alignmentExpr->isIntegerConstantExpr(alignment, Context)) {
-      Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
-           "aligned", alignmentExpr->getSourceRange());
-      return;
-    }
-    
-    Align = alignment.getZExtValue() * 8;
-  }
-
-  d->addAttr(new AlignedAttr(Align));
-}
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
new file mode 100644
index 0000000..8d715f1
--- /dev/null
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -0,0 +1,655 @@
+//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements decl-related attribute processing.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "clang/AST/ASTContext.h"
+
+using namespace clang;
+
+static const FunctionTypeProto *getFunctionProto(Decl *d) {
+  QualType Ty;
+  
+  if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
+    Ty = decl->getType();
+  else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
+    Ty = decl->getType();
+  else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
+    Ty = decl->getUnderlyingType();
+  else
+    return 0;
+  
+  if (Ty->isFunctionPointerType())
+    Ty = Ty->getAsPointerType()->getPointeeType();
+  
+  if (const FunctionType *FnTy = Ty->getAsFunctionType())
+    return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType());
+  
+  return 0;
+}
+
+static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
+  if (!T->isPointerType())
+    return false;
+  
+  T = T->getAsPointerType()->getPointeeType().getCanonicalType();
+  ObjCInterfaceType* ClsT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
+  
+  if (!ClsT)
+    return false;
+  
+  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
+  
+  // FIXME: Should we walk the chain of classes?
+  return ClsName == &Ctx.Idents.get("NSString") ||
+         ClsName == &Ctx.Idents.get("NSMutableString");
+}
+
+void Sema::HandleDeclAttribute(Decl *New, const AttributeList *Attr) {
+  
+  switch (Attr->getKind()) {
+  case AttributeList::AT_vector_size:
+    if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
+      QualType newType = HandleVectorTypeAttribute(vDecl->getType(), Attr);
+      if (!newType.isNull()) // install the new vector type into the decl
+        vDecl->setType(newType);
+    } 
+    if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
+      QualType newType = HandleVectorTypeAttribute(tDecl->getUnderlyingType(), 
+                                                   Attr);
+      if (!newType.isNull()) // install the new vector type into the decl
+        tDecl->setUnderlyingType(newType);
+    }
+    break;
+  case AttributeList::AT_ext_vector_type:
+    if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New))
+      HandleExtVectorTypeAttribute(tDecl, Attr);
+    else
+      Diag(Attr->getLoc(), 
+           diag::err_typecheck_ext_vector_not_typedef);
+    break;
+  case AttributeList::AT_address_space:
+    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
+    break;
+  case AttributeList::AT_mode:
+    // Despite what would be logical, the mode attribute is a decl attribute,
+    // not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
+    // 'G' be HImode, not an intermediate pointer.
+    if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
+      QualType newType = HandleModeTypeAttribute(tDecl->getUnderlyingType(),
+                                                 Attr);
+      tDecl->setUnderlyingType(newType);
+    } else if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
+      QualType newType = HandleModeTypeAttribute(vDecl->getType(), Attr);
+      vDecl->setType(newType);
+    }
+    // FIXME: Diagnostic?
+    break;
+  case AttributeList::AT_alias:      HandleAliasAttribute(New, Attr); break;
+  case AttributeList::AT_deprecated: HandleDeprecatedAttribute(New, Attr);break;
+  case AttributeList::AT_visibility: HandleVisibilityAttribute(New, Attr);break;
+  case AttributeList::AT_weak:       HandleWeakAttribute(New, Attr); break;
+  case AttributeList::AT_dllimport:  HandleDLLImportAttribute(New, Attr); break;
+  case AttributeList::AT_dllexport:  HandleDLLExportAttribute(New, Attr); break;
+  case AttributeList::AT_nothrow:    HandleNothrowAttribute(New, Attr); break;
+  case AttributeList::AT_stdcall:    HandleStdCallAttribute(New, Attr); break;
+  case AttributeList::AT_fastcall:   HandleFastCallAttribute(New, Attr); break;
+  case AttributeList::AT_aligned:    HandleAlignedAttribute(New, Attr); break;
+  case AttributeList::AT_packed:     HandlePackedAttribute(New, Attr); break;
+  case AttributeList::AT_annotate:   HandleAnnotateAttribute(New, Attr); break;
+  case AttributeList::AT_noreturn:   HandleNoReturnAttribute(New, Attr); break;
+  case AttributeList::AT_format:     HandleFormatAttribute(New, Attr); break;
+  case AttributeList::AT_transparent_union:
+    HandleTransparentUnionAttribute(New, Attr);
+    break;
+  default:
+#if 0
+    // TODO: when we have the full set of attributes, warn about unknown ones.
+    Diag(Attr->getLoc(), diag::warn_attribute_ignored,
+         Attr->getName()->getName());
+#endif
+    break;
+  }
+}
+
+void Sema::HandleDeclAttributes(Decl *New, const AttributeList *DeclSpecAttrs,
+                                const AttributeList *DeclaratorAttrs) {
+  if (DeclSpecAttrs == 0 && DeclaratorAttrs == 0) return;
+  
+  while (DeclSpecAttrs) {
+    HandleDeclAttribute(New, DeclSpecAttrs);
+    DeclSpecAttrs = DeclSpecAttrs->getNext();
+  }
+  
+  // If there are any type attributes that were in the declarator, apply them to
+  // its top level type.
+  if (ValueDecl *VD = dyn_cast<ValueDecl>(New)) {
+    QualType DT = VD->getType();
+    ProcessTypeAttributes(DT, DeclaratorAttrs);
+    VD->setType(DT);
+  } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(New)) {
+    QualType DT = TD->getUnderlyingType();
+    ProcessTypeAttributes(DT, DeclaratorAttrs);
+    TD->setUnderlyingType(DT);
+  }
+  
+  while (DeclaratorAttrs) {
+    HandleDeclAttribute(New, DeclaratorAttrs);
+    DeclaratorAttrs = DeclaratorAttrs->getNext();
+  }
+}
+
+void Sema::HandleExtVectorTypeAttribute(TypedefDecl *tDecl, 
+                                        const AttributeList *rawAttr) {
+  QualType curType = tDecl->getUnderlyingType();
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 1) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("1"));
+    return;
+  }
+  Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
+  llvm::APSInt vecSize(32);
+  if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
+         "ext_vector_type", sizeExpr->getSourceRange());
+    return;
+  }
+  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
+  // in conjunction with complex types (pointers, arrays, functions, etc.).
+  Type *canonType = curType.getCanonicalType().getTypePtr();
+  if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_invalid_vector_type,
+         curType.getCanonicalType().getAsString());
+    return;
+  }
+  // unlike gcc's vector_size attribute, the size is specified as the 
+  // number of elements, not the number of bytes.
+  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 
+  
+  if (vectorSize == 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_zero_size,
+         sizeExpr->getSourceRange());
+    return;
+  }
+  // Instantiate/Install the vector type, the number of elements is > 0.
+  tDecl->setUnderlyingType(Context.getExtVectorType(curType, vectorSize));
+  // Remember this typedef decl, we will need it later for diagnostics.
+  ExtVectorDecls.push_back(tDecl);
+}
+
+QualType Sema::HandleVectorTypeAttribute(QualType curType, 
+                                         const AttributeList *rawAttr) {
+  // check the attribute arugments.
+  if (rawAttr->getNumArgs() != 1) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("1"));
+    return QualType();
+  }
+  Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
+  llvm::APSInt vecSize(32);
+  if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
+         "vector_size", sizeExpr->getSourceRange());
+    return QualType();
+  }
+  // navigate to the base type - we need to provide for vector pointers, 
+  // vector arrays, and functions returning vectors.
+  Type *canonType = curType.getCanonicalType().getTypePtr();
+  
+  if (canonType->isPointerType() || canonType->isArrayType() ||
+      canonType->isFunctionType()) {
+    assert(0 && "HandleVector(): Complex type construction unimplemented");
+    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
+     do {
+     if (PointerType *PT = dyn_cast<PointerType>(canonType))
+     canonType = PT->getPointeeType().getTypePtr();
+     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
+     canonType = AT->getElementType().getTypePtr();
+     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
+     canonType = FT->getResultType().getTypePtr();
+     } while (canonType->isPointerType() || canonType->isArrayType() ||
+     canonType->isFunctionType());
+     */
+  }
+  // the base type must be integer or float.
+  if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_invalid_vector_type,
+         curType.getCanonicalType().getAsString());
+    return QualType();
+  }
+  unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(curType));
+  // vecSize is specified in bytes - convert to bits.
+  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 
+  
+  // the vector size needs to be an integral multiple of the type size.
+  if (vectorSize % typeSize) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_invalid_size,
+         sizeExpr->getSourceRange());
+    return QualType();
+  }
+  if (vectorSize == 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_zero_size,
+         sizeExpr->getSourceRange());
+    return QualType();
+  }
+  // Instantiate the vector type, the number of elements is > 0, and not
+  // required to be a power of 2, unlike GCC.
+  return Context.getVectorType(curType, vectorSize/typeSize);
+}
+
+void Sema::HandlePackedAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() > 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+  
+  if (TagDecl *TD = dyn_cast<TagDecl>(d))
+    TD->addAttr(new PackedAttr);
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
+    // If the alignment is less than or equal to 8 bits, the packed attribute
+    // has no effect.
+    if (!FD->getType()->isIncompleteType() &&
+        Context.getTypeAlign(FD->getType()) <= 8)
+      Diag(rawAttr->getLoc(), 
+           diag::warn_attribute_ignored_for_field_of_type,
+           rawAttr->getName()->getName(), FD->getType().getAsString());
+    else
+      FD->addAttr(new PackedAttr);
+  } else
+    Diag(rawAttr->getLoc(), diag::warn_attribute_ignored,
+         rawAttr->getName()->getName());
+}
+
+void Sema::HandleAliasAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 1) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("1"));
+    return;
+  }
+  
+  Expr *Arg = static_cast<Expr*>(rawAttr->getArg(0));
+  Arg = Arg->IgnoreParenCasts();
+  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+  
+  if (Str == 0 || Str->isWide()) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
+         "alias", std::string("1"));
+    return;
+  }
+  
+  const char *Alias = Str->getStrData();
+  unsigned AliasLen = Str->getByteLength();
+  
+  // FIXME: check if target symbol exists in current file
+  
+  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
+}
+
+void Sema::HandleNoReturnAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+  
+  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
+  
+  if (!Fn) {
+    Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
+         "noreturn", "function");
+    return;
+  }
+  
+  d->addAttr(new NoReturnAttr());
+}
+
+void Sema::HandleDeprecatedAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+  
+  d->addAttr(new DeprecatedAttr());
+}
+
+void Sema::HandleVisibilityAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 1) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("1"));
+    return;
+  }
+  
+  Expr *Arg = static_cast<Expr*>(rawAttr->getArg(0));
+  Arg = Arg->IgnoreParenCasts();
+  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+  
+  if (Str == 0 || Str->isWide()) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
+         "visibility", std::string("1"));
+    return;
+  }
+  
+  const char *TypeStr = Str->getStrData();
+  unsigned TypeLen = Str->getByteLength();
+  VisibilityAttr::VisibilityTypes type;
+  
+  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
+    type = VisibilityAttr::DefaultVisibility;
+  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
+    type = VisibilityAttr::HiddenVisibility;
+  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
+    type = VisibilityAttr::HiddenVisibility; // FIXME
+  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
+    type = VisibilityAttr::ProtectedVisibility;
+  else {
+    Diag(rawAttr->getLoc(), diag::warn_attribute_type_not_supported,
+         "visibility", TypeStr);
+    return;
+  }
+  
+  d->addAttr(new VisibilityAttr(type));
+}
+
+void Sema::HandleWeakAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+  
+  d->addAttr(new WeakAttr());
+}
+
+void Sema::HandleDLLImportAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+  
+  d->addAttr(new DLLImportAttr());
+}
+
+void Sema::HandleDLLExportAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+  
+  d->addAttr(new DLLExportAttr());
+}
+
+void Sema::HandleStdCallAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+  
+  d->addAttr(new StdCallAttr());
+}
+
+void Sema::HandleFastCallAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+  
+  d->addAttr(new FastCallAttr());
+}
+
+void Sema::HandleNothrowAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+  
+  d->addAttr(new NoThrowAttr());
+}
+
+/// Handle __attribute__((format(type,idx,firstarg))) attributes
+/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
+void Sema::HandleFormatAttribute(Decl *d, const AttributeList *rawAttr) {
+
+  if (!rawAttr->getParameterName()) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
+           "format", std::string("1"));
+    return;
+  }
+
+  if (rawAttr->getNumArgs() != 2) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("3"));
+    return;
+  }
+
+  // GCC ignores the format attribute on K&R style function
+  // prototypes, so we ignore it as well
+  const FunctionTypeProto *proto = getFunctionProto(d);
+
+  if (!proto) {
+    Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
+           "format", "function");
+    return;
+  }
+
+  // FIXME: in C++ the implicit 'this' function parameter also counts.
+  // this is needed in order to be compatible with GCC
+  // the index must start in 1 and the limit is numargs+1
+  unsigned NumArgs  = proto->getNumArgs();
+  unsigned FirstIdx = 1;
+
+  const char *Format = rawAttr->getParameterName()->getName();
+  unsigned FormatLen = rawAttr->getParameterName()->getLength();
+
+  // Normalize the argument, __foo__ becomes foo.
+  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
+      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
+    Format += 2;
+    FormatLen -= 4;
+  }
+
+  bool Supported = false;
+  bool is_NSString = false;
+  bool is_strftime = false;
+  
+  switch (FormatLen) {
+  default: break;
+  case 5:
+    Supported = !memcmp(Format, "scanf", 5);
+    break;
+  case 6:
+    Supported = !memcmp(Format, "printf", 6);
+    break;
+  case 7:
+    Supported = !memcmp(Format, "strfmon", 7);
+    break;
+  case 8:
+    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 
+                (is_NSString = !memcmp(Format, "NSString", 8));
+    break;
+  }
+      
+  if (!Supported) {
+    Diag(rawAttr->getLoc(), diag::warn_attribute_type_not_supported,
+           "format", rawAttr->getParameterName()->getName());
+    return;
+  }
+
+  // checks for the 2nd argument
+  Expr *IdxExpr = static_cast<Expr *>(rawAttr->getArg(0));
+  llvm::APSInt Idx(Context.getTypeSize(IdxExpr->getType()));
+  if (!IdxExpr->isIntegerConstantExpr(Idx, Context)) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int,
+           "format", std::string("2"), IdxExpr->getSourceRange());
+    return;
+  }
+
+  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_argument_out_of_bounds,
+           "format", std::string("2"), IdxExpr->getSourceRange());
+    return;
+  }
+
+  // FIXME: Do we need to bounds check?
+  unsigned ArgIdx = Idx.getZExtValue() - 1;
+  
+  // make sure the format string is really a string
+  QualType Ty = proto->getArgType(ArgIdx);
+
+  if (is_NSString) {
+    // FIXME: do we need to check if the type is NSString*?  What are
+    //  the semantics?
+    if (!isNSStringType(Ty, Context)) {
+      // FIXME: Should highlight the actual expression that has the
+      // wrong type.
+      Diag(rawAttr->getLoc(), diag::err_format_attribute_not_NSString,
+           IdxExpr->getSourceRange());
+      return;
+    }    
+  } else if (!Ty->isPointerType() ||
+             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
+    // FIXME: Should highlight the actual expression that has the
+    // wrong type.
+    Diag(rawAttr->getLoc(), diag::err_format_attribute_not_string,
+         IdxExpr->getSourceRange());
+    return;
+  }
+
+  // check the 3rd argument
+  Expr *FirstArgExpr = static_cast<Expr *>(rawAttr->getArg(1));
+  llvm::APSInt FirstArg(Context.getTypeSize(FirstArgExpr->getType()));
+  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, Context)) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int,
+           "format", std::string("3"), FirstArgExpr->getSourceRange());
+    return;
+  }
+
+  // check if the function is variadic if the 3rd argument non-zero
+  if (FirstArg != 0) {
+    if (proto->isVariadic()) {
+      ++NumArgs; // +1 for ...
+    } else {
+      Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
+      return;
+    }
+  }
+
+  // strftime requires FirstArg to be 0 because it doesn't read from any variable
+  // the input is just the current time + the format string
+  if (is_strftime) {
+    if (FirstArg != 0) {
+      Diag(rawAttr->getLoc(), diag::err_format_strftime_third_parameter,
+             FirstArgExpr->getSourceRange());
+      return;
+    }
+  // if 0 it disables parameter checking (to use with e.g. va_list)
+  } else if (FirstArg != 0 && FirstArg != NumArgs) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_argument_out_of_bounds,
+           "format", std::string("3"), FirstArgExpr->getSourceRange());
+    return;
+  }
+
+  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
+                            Idx.getZExtValue(), FirstArg.getZExtValue()));
+}
+
+void Sema::HandleTransparentUnionAttribute(Decl *d,
+                                           const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 0) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+
+  TypeDecl *decl = dyn_cast<TypeDecl>(d);
+
+  if (!decl || !Context.getTypeDeclType(decl)->isUnionType()) {
+    Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
+         "transparent_union", "union");
+    return;
+  }
+
+  //QualType QTy = Context.getTypeDeclType(decl);
+  //const RecordType *Ty = QTy->getAsUnionType();
+
+// FIXME
+// Ty->addAttr(new TransparentUnionAttr());
+}
+
+void Sema::HandleAnnotateAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() != 1) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("1"));
+    return;
+  }
+  Expr *argExpr = static_cast<Expr *>(rawAttr->getArg(0));
+  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
+  
+  // Make sure that there is a string literal as the annotation's single
+  // argument.
+  if (!SE) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_annotate_no_string);
+    return;
+  }
+  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
+                                          SE->getByteLength())));
+}
+
+void Sema::HandleAlignedAttribute(Decl *d, const AttributeList *rawAttr) {
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() > 1) {
+    Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("1"));
+    return;
+  }
+
+  unsigned Align = 0;
+  
+  if (rawAttr->getNumArgs() == 0) {
+    // FIXME: This should be the target specific maximum alignment.
+    // (For now we just use 128 bits which is the maximum on X86.
+    Align = 128;
+    return;
+  } else {
+    Expr *alignmentExpr = static_cast<Expr *>(rawAttr->getArg(0));
+    llvm::APSInt alignment(32);
+    if (!alignmentExpr->isIntegerConstantExpr(alignment, Context)) {
+      Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
+           "aligned", alignmentExpr->getSourceRange());
+      return;
+    }
+    
+    Align = alignment.getZExtValue() * 8;
+  }
+
+  d->addAttr(new AlignedAttr(Align));
+}
