From 2a18efef823edb858129e64cfdf6e165ffab71c5 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Thu, 12 Apr 2012 11:23:02 -0700 Subject: [PATCH] Use type conversion machinery when processing expr lists for initializers. Once we're down to something that's not another nested expr list, use TypeConvertExpr() to convert the expression to the type we need. This should allow simplifying a number of the GetConstant() implementations, to remove partial reimplementation of type conversion there. For now, this change finishes off issue #220. --- expr.cpp | 20 ++++++++++++++++++-- tests/func-ptr-initializer.ispc | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 tests/func-ptr-initializer.ispc diff --git a/expr.cpp b/expr.cpp index cbef1622..a804d733 100644 --- a/expr.cpp +++ b/expr.cpp @@ -3662,7 +3662,19 @@ ExprList::GetConstant(const Type *type) const { if (exprs[i] == NULL) return NULL; const Type *elementType = collectionType->GetElementType(i); - llvm::Constant *c = exprs[i]->GetConstant(elementType); + + Expr *expr = exprs[i]; + if (dynamic_cast(expr) == NULL) { + // If there's a simple type conversion from the type of this + // expression to the type we need, then let the regular type + // conversion machinery handle it. + expr = TypeConvertExpr(exprs[i], elementType, "initializer list"); + Assert(expr != NULL); + // Re-establish const-ness if possible + expr = ::Optimize(expr); + } + + llvm::Constant *c = expr->GetConstant(elementType); if (c == NULL) // If this list element couldn't convert to the right constant // type for the corresponding collection member, then give up. @@ -7503,8 +7515,12 @@ FunctionSymbolExpr::GetConstant(const Type *type) const { if (ft == NULL) return NULL; - if (Type::Equal(type, matchingFunc->type) == false) + if (Type::Equal(type, matchingFunc->type) == false) { + Error(pos, "Type of function symbol \"%s\" doesn't match expected type " + "\"%s\".", matchingFunc->type->GetString().c_str(), + type->GetString().c_str()); return NULL; + } return matchingFunc->function; } diff --git a/tests/func-ptr-initializer.ispc b/tests/func-ptr-initializer.ispc new file mode 100644 index 00000000..96537391 --- /dev/null +++ b/tests/func-ptr-initializer.ispc @@ -0,0 +1,28 @@ + +export uniform int width() { return programCount; } + + +typedef float (*func)(); + +float foo(); +float bar(); + +struct X { func f, g; }; + +static uniform X x = { foo, &bar }; + +export void f_f(uniform float RET[], uniform float aFOO[]) { + RET[programIndex] = x.f() + x.g(); +} + +export void result(uniform float RET[]) { + RET[programIndex] = programIndex; +} + +float foo() { + return 2 * programIndex; +} + +float bar() { + return -programIndex; +}