Implement pretty diagnostics when doing on-the-fly vector sizing (for vector component access).

For example, before this commit, the following diagnostics would be emitted...

ocu.c:49:12: error: incompatible types assigning 'float  __attribute__((ocu_vector_type(3)))' to 'float4'
    vec4_2 = vec4.rgb; // shorten
    ~~~~~~ ^ ~~~~~~~~
ocu.c:51:7: error: incompatible types assigning 'float  __attribute__((ocu_vector_type(2)))' to 'float'
    f = vec2.xx; // shorten
    ~ ^ ~~~~~~~

Now, the diagnostics look as you would expect...

ocu.c:49:12: error: incompatible types assigning 'float3' to 'float4'
    vec4_2 = vec4.rgb; // shorten
    ~~~~~~ ^ ~~~~~~~~
ocu.c:51:7: error: incompatible types assigning 'float2' to 'float'
    f = vec2.xx; // shorten
    ~ ^ ~~~~~~~



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40579 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 3053d2e..722452b 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -965,15 +965,11 @@
     }
   }
   if (strcmp(rawAttr->getAttributeName()->getName(), "ocu_vector_type") == 0) {
-    if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
-      QualType newType = HandleOCUVectorTypeAttribute(tDecl->getUnderlyingType(), 
-                                                      rawAttr);
-      if (!newType.isNull()) // install the new vector type into the decl
-        tDecl->setUnderlyingType(newType);
-    } else {
+    if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New))
+      HandleOCUVectorTypeAttribute(tDecl, rawAttr);
+    else
       Diag(rawAttr->getAttributeLoc(), 
            diag::err_typecheck_ocu_vector_not_typedef);
-    }
   }
   // FIXME: add other attributes...
 }
@@ -990,20 +986,21 @@
   }
 }
 
-QualType Sema::HandleOCUVectorTypeAttribute(QualType curType, 
-                                            AttributeList *rawAttr) {
+void Sema::HandleOCUVectorTypeAttribute(TypedefDecl *tDecl, 
+                                        AttributeList *rawAttr) {
+  QualType curType = tDecl->getUnderlyingType();
   // check the attribute arugments.
   if (rawAttr->getNumArgs() != 1) {
     Diag(rawAttr->getAttributeLoc(), diag::err_attribute_wrong_number_arguments,
          std::string("1"));
-    return QualType();
+    return;
   }
   Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
   llvm::APSInt vecSize(32);
   if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
     Diag(rawAttr->getAttributeLoc(), diag::err_attribute_vector_size_not_int,
          sizeExpr->getSourceRange());
-    return QualType();
+    return;
   }
   // unlike gcc's vector_size attribute, we do not allow vectors to be defined
   // in conjunction with complex types (pointers, arrays, functions, etc.).
@@ -1011,7 +1008,7 @@
   if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
     Diag(rawAttr->getAttributeLoc(), diag::err_attribute_invalid_vector_type,
          curType.getCanonicalType().getAsString());
-    return QualType();
+    return;
   }
   // unlike gcc's vector_size attribute, the size is specified as the 
   // number of elements, not the number of bytes.
@@ -1020,10 +1017,12 @@
   if (vectorSize == 0) {
     Diag(rawAttr->getAttributeLoc(), diag::err_attribute_zero_size,
          sizeExpr->getSourceRange());
-    return QualType();
+    return;
   }
-  // Instantiate the vector type, the number of elements is > 0.
-  return Context.getOCUVectorType(curType, vectorSize);
+  // Instantiate/Install the vector type, the number of elements is > 0.
+  tDecl->setUnderlyingType(Context.getOCUVectorType(curType, vectorSize));
+  // Remember this typedef decl, we will need it later for diagnostics.
+  OCUVectorDecls.push_back(tDecl);
 }
 
 QualType Sema::HandleVectorTypeAttribute(QualType curType,