[cfe-commits] r40007 - in /cfe/trunk: AST/ASTContext.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/Basic/DiagnosticKinds.def

Steve Naroff snaroff at apple.com
Wed Jul 18 11:00:27 PDT 2007


Author: snaroff
Date: Wed Jul 18 13:00:27 2007
New Revision: 40007

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

First round of extended vector support. Here is an overview...

- added ocu_vector_type attribute, Sema::HandleOCUVectorTypeAttribute(). 
- added new AST node, OCUVectorType, a subclass of VectorType.
- added ASTContext::getOCUVectorType.
- changed ASTContext::convertToVectorType() to ASTContext::getVectorType(). This is 
unrelated to extended vectors, however I was in the vicinity and it was on my todo list.
Added a FIXME to Sema::HandleVectorTypeAttribute to deal with converting complex types.


Modified:
    cfe/trunk/AST/ASTContext.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=40007&r1=40006&r2=40007&view=diff

==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Wed Jul 18 13:00:27 2007
@@ -392,19 +392,17 @@
   return QualType(New, 0);
 }
 
-/// convertToVectorType - Return the unique reference to a vector type of
-/// the specified element type and size. VectorType can be a pointer, array,
-/// function, or built-in type (i.e. _Bool, integer, or float).
-QualType ASTContext::convertToVectorType(QualType vecType, unsigned NumElts) {
+/// getVectorType - Return the unique reference to a vector type of
+/// the specified element type and size. VectorType must be a built-in type.
+QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
   BuiltinType *baseType;
   
   baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
-  assert(baseType != 0 && 
-         "convertToVectorType(): Complex vector types unimplemented");
+  assert(baseType != 0 && "getVectorType(): Expecting a built-in type");
          
   // Check if we've already instantiated a vector of this type.
   llvm::FoldingSetNodeID ID;
-  VectorType::Profile(ID, vecType, NumElts);      
+  VectorType::Profile(ID, vecType, NumElts, Type::Vector);      
   void *InsertPos = 0;
   if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(VTP, 0);
@@ -413,7 +411,7 @@
   // so fill in the canonical type field.
   QualType Canonical;
   if (!vecType->isCanonical()) {
-    Canonical = convertToVectorType(vecType.getCanonicalType(), NumElts);
+    Canonical = getVectorType(vecType.getCanonicalType(), NumElts);
     
     // Get the new insert position for the node we care about.
     VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -425,6 +423,37 @@
   return QualType(New, 0);
 }
 
+/// getOCUVectorType - Return the unique reference to an OCU vector type of
+/// the specified element type and size. VectorType must be a built-in type.
+QualType ASTContext::getOCUVectorType(QualType vecType, unsigned NumElts) {
+  BuiltinType *baseType;
+  
+  baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
+  assert(baseType != 0 && "getOCUVectorType(): Expecting a built-in type");
+         
+  // Check if we've already instantiated a vector of this type.
+  llvm::FoldingSetNodeID ID;
+  VectorType::Profile(ID, vecType, NumElts, Type::OCUVector);      
+  void *InsertPos = 0;
+  if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(VTP, 0);
+
+  // If the element type isn't canonical, this won't be a canonical type either,
+  // so fill in the canonical type field.
+  QualType Canonical;
+  if (!vecType->isCanonical()) {
+    Canonical = getOCUVectorType(vecType.getCanonicalType(), NumElts);
+    
+    // Get the new insert position for the node we care about.
+    VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!");
+  }
+  OCUVectorType *New = new OCUVectorType(vecType, NumElts, Canonical);
+  VectorTypes.InsertNode(New, InsertPos);
+  Types.push_back(New);
+  return QualType(New, 0);
+}
+
 /// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
 ///
 QualType ASTContext::getFunctionTypeNoProto(QualType ResultTy) {

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

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Wed Jul 18 13:00:27 2007
@@ -153,6 +153,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);
   
   //===--------------------------------------------------------------------===//
   // Statement Parsing Callbacks: SemaStmt.cpp.

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Wed Jul 18 13:00:27 2007
@@ -956,6 +956,17 @@
         tDecl->setUnderlyingType(newType);
     }
   }
+  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 {
+      Diag(rawAttr->getAttributeLoc(), 
+           diag::err_typecheck_ocu_vector_not_typedef);
+    }
+  }
   // FIXME: add other attributes...
 }
 
@@ -971,6 +982,42 @@
   }
 }
 
+QualType Sema::HandleOCUVectorTypeAttribute(QualType curType, 
+                                            AttributeList *rawAttr) {
+  // check the attribute arugments.
+  if (rawAttr->getNumArgs() != 1) {
+    Diag(rawAttr->getAttributeLoc(), 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->getAttributeLoc(), diag::err_attribute_vector_size_not_int,
+         sizeExpr->getSourceRange());
+    return QualType();
+  }
+  // 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->getAttributeLoc(), diag::err_attribute_invalid_vector_type,
+         curType.getCanonicalType().getAsString());
+    return QualType();
+  }
+  // unlike gcc's vector_size attribute, the size is specified as the 
+  // number of elements, not the number of bytes.
+  unsigned vectorSize = vecSize.getZExtValue(); 
+  
+  if (vectorSize == 0) {
+    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_zero_size,
+         sizeExpr->getSourceRange());
+    return QualType();
+  }
+  // Instantiate the vector type, the number of elements is > 0.
+  return Context.getOCUVectorType(curType, vectorSize);
+}
+
 QualType Sema::HandleVectorTypeAttribute(QualType curType, 
                                          AttributeList *rawAttr) {
   // check the attribute arugments.
@@ -990,14 +1037,20 @@
   // vector arrays, and functions returning vectors.
   Type *canonType = curType.getCanonicalType().getTypePtr();
   
-  while (canonType->isPointerType() || canonType->isArrayType() ||
-         canonType->isFunctionType()) {
-    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();
+  if (canonType->isPointerType() || canonType->isArrayType() ||
+      canonType->isFunctionType()) {
+    assert(1 && "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())) {
@@ -1023,6 +1076,6 @@
   // Since OpenCU requires 3 element vectors (OpenCU 5.1.2), we don't restrict
   // the number of elements to be a power of two (unlike GCC).
   // Instantiate the vector type, the number of elements is > 0.
-  return Context.convertToVectorType(curType, vectorSize/typeSize);
+  return Context.getVectorType(curType, vectorSize/typeSize);
 }
 

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 18 13:00:27 2007
@@ -79,10 +79,13 @@
   QualType getArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM,
                         unsigned EltTypeQuals, Expr *NumElts);
                         
-  /// convertToVectorType - Return the unique reference to a vector type of
-  /// the specified element type and size. VectorType can be a pointer, array,
-  /// function, or built-in type (i.e. _Bool, integer, or float).
-  QualType convertToVectorType(QualType VectorType, unsigned NumElts);
+  /// getVectorType - Return the unique reference to a vector type of
+  /// the specified element type and size. VectorType must be a built-in type.
+  QualType getVectorType(QualType VectorType, unsigned NumElts);
+
+  /// getOCUVectorType - Return the unique reference to an OCU vector type of
+  /// the specified element type and size. VectorType must be a built-in type.
+  QualType getOCUVectorType(QualType VectorType, unsigned NumElts);
 
   /// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
   ///

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

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Jul 18 13:00:27 2007
@@ -182,7 +182,7 @@
 class Type {
 public:
   enum TypeClass {
-    Builtin, Complex, Pointer, Reference, Array, Vector,
+    Builtin, Complex, Pointer, Reference, Array, Vector, OCUVector,
     FunctionNoProto, FunctionProto,
     TypeName, Tagged
   };
@@ -450,17 +450,23 @@
   static bool classof(const ArrayType *) { return true; }
 };
 
-/// VectorType - 
-///
+/// VectorType - GCC generic vector type. This type is created using
+/// __attribute__((vector_size(n)), where "n" specifies the vector size in 
+/// bytes. Since the constructor takes the number of vector elements, the 
+/// client is responsible for converting the size into the number of elements.
 class VectorType : public Type, public llvm::FoldingSetNode {
+protected:
   /// ElementType - The element type of the vector.
   QualType ElementType;
   
   /// NumElements - The number of elements in the vector.
   unsigned NumElements;
   
-  VectorType(QualType vecType, unsigned vectorSize, QualType canonType) :
-    Type(Vector, canonType), ElementType(vecType), NumElements(vectorSize) {} 
+  VectorType(QualType vecType, unsigned nElements, QualType canonType) :
+    Type(Vector, canonType), ElementType(vecType), NumElements(nElements) {} 
+  VectorType(TypeClass tc, QualType vecType, unsigned nElements, 
+    QualType canonType) : Type(tc, canonType), ElementType(vecType), 
+    NumElements(nElements) {} 
   friend class ASTContext;  // ASTContext creates these.
 public:
     
@@ -470,17 +476,35 @@
   virtual void getAsStringInternal(std::string &InnerString) const;
   
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getElementType(), getNumElements());
+    Profile(ID, getElementType(), getNumElements(), getTypeClass());
   }
-  static void Profile(llvm::FoldingSetNodeID &ID,
-                      QualType ElementType, unsigned NumElements) {
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, 
+                      unsigned NumElements, TypeClass TypeClass) {
     ID.AddPointer(ElementType.getAsOpaquePtr());
     ID.AddInteger(NumElements);
+    ID.AddInteger(TypeClass);
+  }
+  static bool classof(const Type *T) { 
+    return T->getTypeClass() == Vector || T->getTypeClass() == OCUVector; 
   }
-  static bool classof(const Type *T) { return T->getTypeClass() == Vector; }
   static bool classof(const VectorType *) { return true; }
 };
 
+/// OCUVectorType - Extended vector type. This type is created using
+/// __attribute__((ocu_vector_type(n)), where "n" is the number of elements.
+/// Unlike vector_size, ocu_vector_type is only allowed on typedef's.
+/// This class will enable syntactic extensions, like C++ style initializers.
+class OCUVectorType : public VectorType {
+  OCUVectorType(QualType vecType, unsigned nElements, QualType canonType) :
+    VectorType(OCUVector, vecType, nElements, canonType) {} 
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  static bool classof(const VectorType *T) { 
+    return T->getTypeClass() == OCUVector; 
+  }
+  static bool classof(const OCUVectorType *) { return true; }
+};
+
 /// FunctionType - C99 6.7.5.3 - Function Declarators.  This is the common base
 /// class of FunctionTypeNoProto and FunctionTypeProto.
 ///

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=40007&r1=40006&r2=40007&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 18 13:00:27 2007
@@ -441,6 +441,8 @@
      "zero vector size")
 DIAG(err_typecheck_vector_not_convertable, ERROR,
      "can't convert between vector values of different size ('%0' and '%1')")
+DIAG(err_typecheck_ocu_vector_not_typedef, ERROR,
+     "ocu_vector_type only applies to types, not variables")
 
 // Function Parameter Semantic Analysis.
 DIAG(err_void_param_with_identifier, ERROR,





More information about the cfe-commits mailing list