]> granicus.if.org Git - clang/commitdiff
Implement pretty diagnostics when doing on-the-fly vector sizing (for vector componen...
authorSteve Naroff <snaroff@apple.com>
Sun, 29 Jul 2007 16:33:31 +0000 (16:33 +0000)
committerSteve Naroff <snaroff@apple.com>
Sun, 29 Jul 2007 16:33:31 +0000 (16:33 +0000)
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

Sema/Sema.h
Sema/SemaDecl.cpp
Sema/SemaExpr.cpp
include/clang/AST/Decl.h

index 589161bfab8633923d5e79c9add36d81e5539cc5..ea724ab44b2e05c406032c99cfd6735acfe4c489 100644 (file)
@@ -39,7 +39,8 @@ namespace clang {
   class LabelStmt;
   class SwitchStmt;
   class OCUVectorType;
-  
+  class TypedefDecl;
+
 /// Sema - This implements semantic analysis and AST building for C.
 class Sema : public Action {
   Preprocessor &PP;
@@ -62,6 +63,11 @@ class Sema : public Action {
   llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
   
   llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
+  
+  /// OCUVectorDecls - This is a list all the OCU vector types. This allows
+  /// us to associate a raw vector type with one of the OCU type names.
+  /// This is only necessary for issuing pretty diagnostics.
+  llvm::SmallVector<TypedefDecl*, 24> OCUVectorDecls;
 public:
   Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup);
   
@@ -158,7 +164,7 @@ private:
   // for the variable, measured in bytes. If curType and rawAttr are well
   // formed, this routine will return a new vector type.
   QualType HandleVectorTypeAttribute(QualType curType, AttributeList *rawAttr);
-  QualType HandleOCUVectorTypeAttribute(QualType curType, AttributeList *rawAttr);
+  void HandleOCUVectorTypeAttribute(TypedefDecl *d, AttributeList *rawAttr);
   
   //===--------------------------------------------------------------------===//
   // Statement Parsing Callbacks: SemaStmt.cpp.
index 3053d2e2a8a1ba1a377131c8b3fed2de1ead3c17..722452b51a4d886c4c876f9ec9e761e4f1d09d9c 100644 (file)
@@ -965,15 +965,11 @@ void Sema::HandleDeclAttribute(Decl *New, AttributeList *rawAttr) {
     }
   }
   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 @@ void Sema::HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix,
   }
 }
 
-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 @@ QualType Sema::HandleOCUVectorTypeAttribute(QualType curType,
   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 @@ QualType Sema::HandleOCUVectorTypeAttribute(QualType curType,
   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, 
index 445b6b566887ab7c8de334dd758566a14b9aa04e..8646c1a792722583f6c04f89df078e7e57426a3b 100644 (file)
@@ -387,7 +387,15 @@ CheckOCUVectorComponent(QualType baseType, SourceLocation OpLoc,
   unsigned CompSize = strlen(CompName.getName());
   if (CompSize == 1)
     return vecType->getElementType();
-  return Context.getOCUVectorType(vecType->getElementType(), CompSize);
+    
+  QualType VT = Context.getOCUVectorType(vecType->getElementType(), CompSize);
+  // Now look up the TypeDefDecl from the vector type. Without this, 
+  // diagostics look bad. We want OCU vector types to appear built-in.
+  for (unsigned i = 0, e = OCUVectorDecls.size(); i != e; ++i) {
+    if (OCUVectorDecls[i]->getUnderlyingType() == VT)
+      return Context.getTypedefType(OCUVectorDecls[i]);
+  }
+  return VT; // should never get here (a typedef type should always be found).
 }
 
 Action::ExprResult Sema::
index b37ab1f99f959b5af52118590ec81c8848ef47fc..a67762a6746deeba5c755e8fb4f0adb9fde11b18 100644 (file)
@@ -313,7 +313,6 @@ protected:
   TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
     : Decl(DK, L, Id, PrevDecl), TypeForDecl(0) {}
 public:
-  
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {
     return D->getKind() >= Typedef && D->getKind() <= Enum;