[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