Make ProcessDeclAttributes walk the declarator structure pulling 
decl attributes out of the various places they can hide.  This makes
us correctly reject things like this:

t.c:2:22: error: mode attribute only supported for integer and floating-point types
  int **__attribute((mode(HI)))* i32;
                     ^

because you can't make a pointer be HImode.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52876 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index cdb5485..2890531 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -16,9 +16,12 @@
 #include "clang/Basic/TargetInfo.h"
 using namespace clang;
 
+//===----------------------------------------------------------------------===//
+//  Helper functions
+//===----------------------------------------------------------------------===//
+
 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))
@@ -54,27 +57,44 @@
          ClsName == &Ctx.Idents.get("NSMutableString");
 }
 
-void Sema::ProcessDeclAttributes(Decl *D, Declarator &PD) {
-  const AttributeList *DeclSpecAttrs = PD.getDeclSpec().getAttributes();
-  const AttributeList *DeclaratorAttrs = PD.getAttributes();
-  
-  if (DeclSpecAttrs == 0 && DeclaratorAttrs == 0) return;
+//===----------------------------------------------------------------------===//
+// Top Level Sema Entry Points
+//===----------------------------------------------------------------------===//
 
-  ProcessDeclAttributeList(D, DeclSpecAttrs);
+/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
+/// it, apply them to D.  This is a bit tricky because PD can have attributes
+/// specified in many different places, and we need to find and apply them all.
+void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
+  // Apply decl attributes from the DeclSpec if present.
+  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
+    ProcessDeclAttributeList(D, Attrs);
+
+  // Walk the declarator structure, applying decl attributes that were in a type
+  // position to the decl itself.  This handles cases like:
+  //   int *__attr__(x)** D;
+  // when X is a decl attribute.
+  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
+    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
+      ProcessDeclAttributeList(D, Attrs);
   
-  // If there are any type attributes that were in the declarator, apply them to
-  // its top level type.
-  if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
-    QualType DT = VD->getType();
-    ProcessTypeAttributes(DT, DeclaratorAttrs);
-    VD->setType(DT);
-  } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
-    QualType DT = TD->getUnderlyingType();
-    ProcessTypeAttributes(DT, DeclaratorAttrs);
-    TD->setUnderlyingType(DT);
+  // Finally, apply any attributes on the decl itself.
+  if (const AttributeList *Attrs = PD.getAttributes()) {
+    ProcessDeclAttributeList(D, Attrs);
+   
+    // If there are any type attributes that were in the declarator, apply them to
+    // its top-level type.
+    // FIXME: we shouldn't allow type attributes here. :(
+    if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
+      QualType DT = VD->getType();
+      ProcessTypeAttributes(DT, Attrs);
+      VD->setType(DT);
+    } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+      QualType DT = TD->getUnderlyingType();
+      ProcessTypeAttributes(DT, Attrs);
+      TD->setUnderlyingType(DT);
+    }
+    // FIXME: field decl?
   }
-  
-  ProcessDeclAttributeList(D, DeclaratorAttrs);
 }
 
 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified
@@ -126,6 +146,10 @@
   }
 }
 
+//===----------------------------------------------------------------------===//
+// Attribute Implementations
+//===----------------------------------------------------------------------===//
+
 void Sema::HandleExtVectorTypeAttribute(Decl *d, const AttributeList &Attr) {
   TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
   if (tDecl == 0) {