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

Steve Naroff snaroff at apple.com
Wed Jul 11 09:47:27 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:47:27 2007
New Revision: 39715

URL: http://llvm.org/viewvc/llvm-project?rev=39715&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
- Finished semantic analysis for vectors, added some diagnostics.
- Added AST for vectors (instantiation, installation into the decl).
- Fixed bug in ParseArraySubscriptExpr()...this crasher was introduced by me
when we added the range support.
- Turned pedantic off by default. Since vectors are gcc extensions, having
pedantic on by default was annoying. Turning it off by default is  also
consistent with gcc (but this wasn't my primary motivation).
- Tweaked some comments and diagnostics.

Note: The type checking code is still under construction (for vectors). This
will be my next check-in.

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

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

==============================================================================
--- cfe/cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/cfe/trunk/AST/ASTContext.cpp Wed Jul 11 11:47:27 2007
@@ -254,6 +254,39 @@
   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) {
+  BuiltinType *baseType;
+  
+  baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
+  assert(baseType != 0 && 
+         "convertToVectorType(): Complex vector types unimplemented");
+         
+  // Check if we've already instantiated a vector of this type.
+  llvm::FoldingSetNodeID ID;
+  VectorType::Profile(ID, vecType, NumElts);      
+  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 = convertToVectorType(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!");
+  }
+  VectorType *New = new VectorType(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/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39715&r1=39714&r2=39715&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:47:27 2007
@@ -17,6 +17,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Support/Streams.h"
+#include "llvm/ADT/StringExtras.h"
 using namespace clang;
 
 Type::~Type() {}
@@ -378,6 +379,31 @@
   }
 }
 
+// FIXME: need to use TargetInfo to derive the target specific sizes. This
+// implementation will suffice for play with vector support.
+unsigned BuiltinType::getSize() const {
+  switch (getKind()) {
+  default: assert(0 && "Unknown builtin type!");
+  case Void:              return 0;
+  case Bool:
+  case Char_S:
+  case Char_U:            return sizeof(char) * 8;
+  case SChar:             return sizeof(signed char) * 8;
+  case Short:             return sizeof(short) * 8;
+  case Int:               return sizeof(int) * 8;
+  case Long:              return sizeof(long) * 8;
+  case LongLong:          return sizeof(long long) * 8;
+  case UChar:             return sizeof(unsigned char) * 8;
+  case UShort:            return sizeof(unsigned short) * 8;
+  case UInt:              return sizeof(unsigned int) * 8;
+  case ULong:             return sizeof(unsigned long) * 8;
+  case ULongLong:         return sizeof(unsigned long long) * 8;
+  case Float:             return sizeof(float) * 8;
+  case Double:            return sizeof(double) * 8;
+  case LongDouble:        return sizeof(long double) * 8;
+  }
+}
+
 void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
                                 QualType* ArgTys,
                                 unsigned NumArgs, bool isVariadic) {
@@ -497,6 +523,14 @@
   ElementType.getAsStringInternal(S);
 }
 
+void VectorType::getAsStringInternal(std::string &S) const {
+  S += " __attribute__(( vector_size(";
+  // FIXME: handle types that are != 32 bits.
+  S += llvm::utostr_32(NumElements*4); // convert back to bytes.
+  S += ") ))";
+  ElementType.getAsStringInternal(S);
+}
+
 void FunctionTypeNoProto::getAsStringInternal(std::string &S) const {
   // If needed for precedence reasons, wrap the inner part in grouping parens.
   if (!S.empty())

Modified: cfe/cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Driver/clang.cpp?rev=39715&r1=39714&r2=39715&view=diff

==============================================================================
--- cfe/cfe/trunk/Driver/clang.cpp (original)
+++ cfe/cfe/trunk/Driver/clang.cpp Wed Jul 11 11:47:27 2007
@@ -301,7 +301,7 @@
 WarningsAsErrors("Werror", llvm::cl::desc("Treat all warnings as errors"));
 
 static llvm::cl::opt<bool>
-WarnOnExtensions("pedantic", llvm::cl::init(true),
+WarnOnExtensions("pedantic", llvm::cl::init(false),
                  llvm::cl::desc("Issue a warning on uses of GCC extensions"));
 
 static llvm::cl::opt<bool>

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

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:47:27 2007
@@ -152,7 +152,7 @@
   // The raw attribute should contain precisely 1 argument, the vector size 
   // for the variable, measured in bytes. If curType and rawAttr are well
   // formed, this routine will return a new vector type.
-  void *HandleVectorTypeAttribute(QualType curType, AttributeList *rawAttr);
+  QualType HandleVectorTypeAttribute(QualType curType, AttributeList *rawAttr);
   
   //===--------------------------------------------------------------------===//
   // Statement Parsing Callbacks: SemaStmt.cpp.

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:47:27 2007
@@ -941,12 +941,17 @@
 void Sema::HandleDeclAttribute(Decl *New, AttributeList *rawAttr) {
   if (strcmp(rawAttr->getAttributeName()->getName(), "vector_size") == 0) {
     if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
-      HandleVectorTypeAttribute(vDecl->getType(), rawAttr);
+      QualType newType = HandleVectorTypeAttribute(vDecl->getType(), rawAttr);
       // install the new vector type into the decl
+      QualType oldType = vDecl->setType(newType);
+      // FIXME: deal with memory management for oldType!
     } 
     if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
-      HandleVectorTypeAttribute(tDecl->getUnderlyingType(), rawAttr);
+      QualType newType = HandleVectorTypeAttribute(tDecl->getUnderlyingType(), 
+                                                   rawAttr);
       // install the new vector type into the decl
+      QualType oldType = tDecl->setUnderlyingType(newType);
+      // FIXME: deal with memory management for oldType!
     }
   }
   // FIXME: add other attributes...
@@ -964,20 +969,20 @@
   }
 }
 
-void *Sema::HandleVectorTypeAttribute(QualType curType, 
+QualType Sema::HandleVectorTypeAttribute(QualType curType, 
                                       AttributeList *rawAttr) {
-  // check the attribute arugments
+  // check the attribute arugments.
   if (rawAttr->getNumArgs() != 1) {
     Diag(rawAttr->getAttributeLoc(), diag::err_attribute_wrong_number_arguments,
          std::string("1"));
-    return 0;
+    return QualType();
   }
   Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
   llvm::APSInt vecSize(32);
   if (!sizeExpr->isIntegerConstantExpr(vecSize)) {
     Diag(rawAttr->getAttributeLoc(), diag::err_attribute_vector_size_not_int,
          sizeExpr->getSourceRange());
-    return 0;
+    return QualType();
   }
   // navigate to the base type - we need to provide for vector pointers, 
   // vector arrays, and functions returning vectors.
@@ -996,11 +1001,27 @@
   if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
     Diag(rawAttr->getAttributeLoc(), diag::err_attribute_invalid_vector_type,
          curType.getCanonicalType().getAsString());
-    return 0;
+    return QualType();
   }
-  // FIXME: check that the vector size is a multiple of the type size (and
-  // not 0). check that the vector components are a power of two. Last, and
-  // certainly not least, instantiate a vector type AST node!
-  return 0;
+  BuiltinType *baseType = cast<BuiltinType>(canonType);
+  unsigned typeSize = baseType->getSize();
+  // vecSize is specified in bytes - convert to bits.
+  unsigned vectorSize = vecSize.getZExtValue() * 8; 
+  
+  // the vector size needs to be an integral multiple of the type size.
+  if (vectorSize % typeSize) {
+    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_invalid_size,
+         sizeExpr->getSourceRange());
+    return QualType();
+  }
+  if (vectorSize == 0) {
+    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_zero_size,
+         sizeExpr->getSourceRange());
+    return QualType();
+  }
+  // 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);
 }
 

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:47:27 2007
@@ -304,8 +304,9 @@
     baseExpr = static_cast<Expr *>(Idx);
     indexExpr = static_cast<Expr *>(Base);
   } else {
-    return Diag(baseExpr->getLocStart(), diag::err_typecheck_subscript_value, 
-                baseExpr->getSourceRange());
+    return Diag(static_cast<Expr *>(Base)->getLocStart(), 
+                diag::err_typecheck_subscript_value, 
+                static_cast<Expr *>(Base)->getSourceRange());
   }              
   // C99 6.5.2.1p1
   if (!indexType->isIntegerType()) {
@@ -762,7 +763,7 @@
 {
   QualType lhsType = lex->getType(), rhsType = rex->getType();
   QualType resType = UsualArithmeticConversions(lhsType, rhsType);
-  
+
   // handle the common case first (both operands are arithmetic).
   if (resType->isArithmeticType())
     return resType;

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 11 11:47:27 2007
@@ -30,6 +30,7 @@
   llvm::FoldingSet<PointerType> PointerTypes;
   llvm::FoldingSet<ReferenceType> ReferenceTypes;
   llvm::FoldingSet<ArrayType> ArrayTypes;
+  llvm::FoldingSet<VectorType> VectorTypes;
   llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
   llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
 public:
@@ -70,6 +71,11 @@
   /// specified element type.
   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);
 
   /// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
   ///

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:47:27 2007
@@ -128,6 +128,11 @@
             Decl *PrevDecl) : Decl(DK, L, Id, PrevDecl), DeclType(T) {}
 public:
   QualType getType() const { return DeclType; }
+  QualType setType(QualType newType) {
+    QualType oldType = DeclType;
+    DeclType = newType;
+    return oldType;
+  }
   QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
   
   // Implement isa/cast/dyncast/etc.
@@ -325,7 +330,12 @@
     : TypeDecl(Typedef, L, Id, PrevDecl), UnderlyingType(T) {}
   
   QualType getUnderlyingType() const { return UnderlyingType; }
-  
+  QualType setUnderlyingType(QualType newType) {
+    QualType oldType = UnderlyingType;
+    UnderlyingType = newType;
+    return oldType;
+  }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return D->getKind() == Typedef; }
   static bool classof(const TypedefDecl *D) { return true; }

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:47:27 2007
@@ -179,7 +179,8 @@
 class Type {
 public:
   enum TypeClass {
-    Builtin, Complex, Pointer, Reference, Array, FunctionNoProto, FunctionProto,
+    Builtin, Complex, Pointer, Reference, Array, Vector,
+    FunctionNoProto, FunctionProto,
     TypeName, Tagged
   };
 private:
@@ -304,6 +305,9 @@
   Kind getKind() const { return TypeKind; }
   const char *getName() const;
   
+  // the number of bits to represent the builtin type.
+  unsigned getSize() const;
+  
   virtual void getAsStringInternal(std::string &InnerString) const;
   
   static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
@@ -444,6 +448,37 @@
   static bool classof(const ArrayType *) { return true; }
 };
 
+/// VectorType - 
+///
+class VectorType : public Type, public llvm::FoldingSetNode {
+  /// 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) {} 
+  friend class ASTContext;  // ASTContext creates these.
+public:
+    
+  QualType getElementType() const { return ElementType; }
+  unsigned getNumElements() const { return NumElements; } 
+
+  virtual void getAsStringInternal(std::string &InnerString) const;
+  
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getElementType(), getNumElements());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      QualType ElementType, unsigned NumElements) {
+    ID.AddPointer(ElementType.getAsOpaquePtr());
+    ID.AddInteger(NumElements);
+  }
+  static bool classof(const Type *T) { return T->getTypeClass() == Vector; }
+  static bool classof(const VectorType *) { return true; }
+};
+
 /// FunctionType - C99 6.7.5.3 - Function Declarators.  This is the common base
 /// class of FunctionTypeNoProto and FunctionTypeProto.
 ///

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:47:27 2007
@@ -430,11 +430,15 @@
 
 // Attributes
 DIAG(err_attribute_wrong_number_arguments, ERROR,
-     "attribute requires precisely %0 argument")
+     "attribute requires %0 argument(s)")
 DIAG(err_attribute_invalid_vector_type, ERROR,
      "invalid vector type '%0'")
 DIAG(err_attribute_vector_size_not_int, ERROR,
-     "vector_size requires integer constant (attribute ignored)")
+     "vector_size requires integer constant")
+DIAG(err_attribute_invalid_size, ERROR,
+     "vector size not an integral multiple of component size")
+DIAG(err_attribute_zero_size, ERROR,
+     "zero vector size")
 
 // Function Parameter Semantic Analysis.
 DIAG(err_void_param_with_identifier, ERROR,





More information about the cfe-commits mailing list