[cfe-commits] r40579 - in /cfe/trunk: Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp include/clang/AST/Decl.h

Steve Naroff snaroff at apple.com
Sun Jul 29 09:33:32 PDT 2007


Author: snaroff
Date: Sun Jul 29 11:33:31 2007
New Revision: 40579

URL: http://llvm.org/viewvc/llvm-project?rev=40579&view=rev
Log:

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
    ~ ^ ~~~~~~~


Modified:
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/include/clang/AST/Decl.h

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=40579&r1=40578&r2=40579&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Sun Jul 29 11:33:31 2007
@@ -39,7 +39,8 @@
   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 @@
   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 @@
   // 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.

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=40579&r1=40578&r2=40579&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Sun Jul 29 11:33:31 2007
@@ -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, 

Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=40579&r1=40578&r2=40579&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Sun Jul 29 11:33:31 2007
@@ -387,7 +387,15 @@
   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::

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=40579&r1=40578&r2=40579&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sun Jul 29 11:33:31 2007
@@ -313,7 +313,6 @@
   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;





More information about the cfe-commits mailing list