|
@@ -44,7 +44,7 @@ SpirvInstruction *InitListHandler::processCast(QualType toType,
|
|
|
initializers.clear();
|
|
|
scalars.clear();
|
|
|
|
|
|
- initializers.push_back(expr);
|
|
|
+ initializers.push_back(theEmitter.loadIfGLValue(expr));
|
|
|
|
|
|
return doProcess(toType, expr->getExprLoc());
|
|
|
}
|
|
@@ -76,22 +76,20 @@ void InitListHandler::flatten(const InitListExpr *expr) {
|
|
|
init->IgnoreParenNoopCasts(theEmitter.getASTContext()))) {
|
|
|
flatten(subInitList);
|
|
|
} else {
|
|
|
- initializers.push_back(init);
|
|
|
+ initializers.push_back(theEmitter.loadIfGLValue(init));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void InitListHandler::decompose(const Expr *expr) {
|
|
|
- const QualType type = expr->getType();
|
|
|
+void InitListHandler::decompose(SpirvInstruction *inst) {
|
|
|
+ const QualType type = inst->getAstResultType();
|
|
|
|
|
|
if (hlsl::IsHLSLVecType(type)) {
|
|
|
- auto *vec = theEmitter.loadIfGLValue(expr);
|
|
|
const QualType elemType = hlsl::GetHLSLVecElementType(type);
|
|
|
const auto size = hlsl::GetHLSLVecSize(type);
|
|
|
|
|
|
- decomposeVector(vec, elemType, size);
|
|
|
+ decomposeVector(inst, elemType, size);
|
|
|
} else if (hlsl::IsHLSLMatType(type)) {
|
|
|
- auto *mat = theEmitter.loadIfGLValue(expr);
|
|
|
const QualType elemType = hlsl::GetHLSLMatElementType(type);
|
|
|
|
|
|
uint32_t rowCount = 0, colCount = 0;
|
|
@@ -99,12 +97,12 @@ void InitListHandler::decompose(const Expr *expr) {
|
|
|
|
|
|
if (rowCount == 1 || colCount == 1) {
|
|
|
// This also handles the scalar case
|
|
|
- decomposeVector(mat, elemType, rowCount == 1 ? colCount : rowCount);
|
|
|
+ decomposeVector(inst, elemType, rowCount == 1 ? colCount : rowCount);
|
|
|
} else {
|
|
|
for (uint32_t i = 0; i < rowCount; ++i)
|
|
|
for (uint32_t j = 0; j < colCount; ++j) {
|
|
|
auto *element =
|
|
|
- spvBuilder.createCompositeExtract(elemType, mat, {i, j});
|
|
|
+ spvBuilder.createCompositeExtract(elemType, inst, {i, j});
|
|
|
scalars.emplace_back(element, elemType);
|
|
|
}
|
|
|
}
|
|
@@ -130,8 +128,8 @@ bool InitListHandler::tryToSplitStruct() {
|
|
|
if (initializers.empty())
|
|
|
return false;
|
|
|
|
|
|
- auto *init = const_cast<Expr *>(initializers.back());
|
|
|
- const QualType initType = init->getType();
|
|
|
+ auto *init = initializers.back();
|
|
|
+ const QualType initType = init->getAstResultType();
|
|
|
if (!initType->isStructureType() ||
|
|
|
// Sampler types will pass the above check but we cannot split it.
|
|
|
isSampler(initType))
|
|
@@ -140,19 +138,16 @@ bool InitListHandler::tryToSplitStruct() {
|
|
|
// We are certain the current intializer will be replaced by now.
|
|
|
initializers.pop_back();
|
|
|
|
|
|
- const auto &context = theEmitter.getASTContext();
|
|
|
const auto *structDecl = initType->getAsStructureType()->getDecl();
|
|
|
|
|
|
// Create MemberExpr for each field of the struct
|
|
|
- llvm::SmallVector<const Expr *, 4> fields;
|
|
|
+ llvm::SmallVector<SpirvInstruction *, 4> fields;
|
|
|
+ uint32_t i = 0;
|
|
|
for (auto *field : structDecl->fields()) {
|
|
|
- fields.push_back(MemberExpr::Create(
|
|
|
- context, init, /*isarraw*/ false, /*OperatorLoc*/ {},
|
|
|
- /*QualifierLoc*/ {}, /*TemplateKWLoc*/ {}, field,
|
|
|
- DeclAccessPair::make(field, AS_none),
|
|
|
- DeclarationNameInfo(field->getDeclName(), /*NameLoc*/ {}),
|
|
|
- /*TemplateArgumentListInfo*/ nullptr, field->getType(),
|
|
|
- init->getValueKind(), OK_Ordinary));
|
|
|
+ auto *extract =
|
|
|
+ spvBuilder.createCompositeExtract(field->getType(), init, {i});
|
|
|
+ fields.push_back(extract);
|
|
|
+ ++i;
|
|
|
}
|
|
|
|
|
|
// Push in the reverse order
|
|
@@ -165,8 +160,8 @@ bool InitListHandler::tryToSplitConstantArray() {
|
|
|
if (initializers.empty())
|
|
|
return false;
|
|
|
|
|
|
- auto *init = const_cast<Expr *>(initializers.back());
|
|
|
- const QualType initType = init->getType();
|
|
|
+ auto *init = initializers.back();
|
|
|
+ const QualType initType = init->getAstResultType();
|
|
|
if (!initType->isConstantArrayType())
|
|
|
return false;
|
|
|
|
|
@@ -174,7 +169,6 @@ bool InitListHandler::tryToSplitConstantArray() {
|
|
|
initializers.pop_back();
|
|
|
|
|
|
const auto &context = theEmitter.getASTContext();
|
|
|
- const auto u32Type = context.getIntTypeForBitwidth(32, /*sigined*/ 0);
|
|
|
|
|
|
const auto *arrayType = context.getAsConstantArrayType(initType);
|
|
|
const auto elemType = arrayType->getElementType();
|
|
@@ -184,14 +178,10 @@ bool InitListHandler::tryToSplitConstantArray() {
|
|
|
// Create ArraySubscriptExpr for each element of the array
|
|
|
// TODO: It will generate lots of elements if the array size is very large.
|
|
|
// But do we have a better solution?
|
|
|
- llvm::SmallVector<const Expr *, 4> elements;
|
|
|
+ llvm::SmallVector<SpirvInstruction *, 4> elements;
|
|
|
for (uint32_t i = 0; i < size; ++i) {
|
|
|
- const auto iVal =
|
|
|
- llvm::APInt(/*numBits*/ 32, uint64_t(i), /*isSigned*/ false);
|
|
|
- auto *index = IntegerLiteral::Create(context, iVal, u32Type, {});
|
|
|
- const auto *element = new (context)
|
|
|
- ArraySubscriptExpr(init, index, elemType, VK_LValue, OK_Ordinary, {});
|
|
|
- elements.push_back(element);
|
|
|
+ auto *extract = spvBuilder.createCompositeExtract(elemType, init, {i});
|
|
|
+ elements.push_back(extract);
|
|
|
}
|
|
|
|
|
|
// Push in the reverse order
|
|
@@ -251,16 +241,15 @@ InitListHandler::createInitForBuiltinType(QualType type,
|
|
|
while (tryToSplitStruct() || tryToSplitConstantArray())
|
|
|
;
|
|
|
|
|
|
- const Expr *init = initializers.back();
|
|
|
+ auto *init = initializers.back();
|
|
|
initializers.pop_back();
|
|
|
|
|
|
- if (!init->getType()->isBuiltinType()) {
|
|
|
+ if (!init->getAstResultType()->isBuiltinType()) {
|
|
|
decompose(init);
|
|
|
return createInitForBuiltinType(type, srcLoc);
|
|
|
}
|
|
|
|
|
|
- auto *value = theEmitter.loadIfGLValue(init);
|
|
|
- return theEmitter.castToType(value, init->getType(), type, srcLoc);
|
|
|
+ return theEmitter.castToType(init, init->getAstResultType(), type, srcLoc);
|
|
|
}
|
|
|
|
|
|
SpirvInstruction *
|
|
@@ -275,10 +264,10 @@ InitListHandler::createInitForVectorType(QualType elemType, uint32_t count,
|
|
|
while (tryToSplitStruct() || tryToSplitConstantArray())
|
|
|
;
|
|
|
|
|
|
- const Expr *init = initializers.back();
|
|
|
+ auto *init = initializers.back();
|
|
|
|
|
|
- if (hlsl::IsHLSLVecType(init->getType()) &&
|
|
|
- hlsl::GetHLSLVecSize(init->getType()) == count) {
|
|
|
+ if (hlsl::IsHLSLVecType(init->getAstResultType()) &&
|
|
|
+ hlsl::GetHLSLVecSize(init->getAstResultType()) == count) {
|
|
|
initializers.pop_back();
|
|
|
/// HLSL vector types are parameterized templates and we cannot
|
|
|
/// construct them. So we construct an ExtVectorType here instead.
|
|
@@ -286,8 +275,8 @@ InitListHandler::createInitForVectorType(QualType elemType, uint32_t count,
|
|
|
/// in all type casting methods in SpirvEmitter.
|
|
|
const auto toVecType =
|
|
|
theEmitter.getASTContext().getExtVectorType(elemType, count);
|
|
|
- return theEmitter.castToType(theEmitter.loadIfGLValue(init),
|
|
|
- init->getType(), toVecType, srcLoc);
|
|
|
+ return theEmitter.castToType(init, init->getAstResultType(), toVecType,
|
|
|
+ srcLoc);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -321,17 +310,18 @@ InitListHandler::createInitForMatrixType(QualType matrixType,
|
|
|
while (tryToSplitStruct() || tryToSplitConstantArray())
|
|
|
;
|
|
|
|
|
|
- const Expr *init = initializers.back();
|
|
|
+ auto *init = initializers.back();
|
|
|
|
|
|
- if (hlsl::IsHLSLMatType(init->getType())) {
|
|
|
+ if (hlsl::IsHLSLMatType(init->getAstResultType())) {
|
|
|
uint32_t initRowCount = 0, initColCount = 0;
|
|
|
- hlsl::GetHLSLMatRowColCount(init->getType(), initRowCount, initColCount);
|
|
|
+ hlsl::GetHLSLMatRowColCount(init->getAstResultType(), initRowCount,
|
|
|
+ initColCount);
|
|
|
|
|
|
if (rowCount == initRowCount && colCount == initColCount) {
|
|
|
initializers.pop_back();
|
|
|
// TODO: We only support FP matrices now. Do type cast here after
|
|
|
// adding more matrix types.
|
|
|
- return theEmitter.loadIfGLValue(init);
|
|
|
+ return init;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -362,12 +352,13 @@ SpirvInstruction *InitListHandler::createInitForStructType(QualType type) {
|
|
|
while (tryToSplitConstantArray())
|
|
|
;
|
|
|
|
|
|
- const Expr *init = initializers.back();
|
|
|
+ auto *init = initializers.back();
|
|
|
// We can only avoid decomposing and reconstructing when the type is
|
|
|
// exactly the same.
|
|
|
- if (type.getCanonicalType() == init->getType().getCanonicalType()) {
|
|
|
+ if (type.getCanonicalType() ==
|
|
|
+ init->getAstResultType().getCanonicalType()) {
|
|
|
initializers.pop_back();
|
|
|
- return theEmitter.loadIfGLValue(init);
|
|
|
+ return init;
|
|
|
}
|
|
|
|
|
|
// Otherwise, if the next initializer is a struct, it is not of the same
|
|
@@ -401,12 +392,13 @@ InitListHandler::createInitForConstantArrayType(QualType type,
|
|
|
while (tryToSplitStruct())
|
|
|
;
|
|
|
|
|
|
- const Expr *init = initializers.back();
|
|
|
+ auto *init = initializers.back();
|
|
|
// We can only avoid decomposing and reconstructing when the type is
|
|
|
// exactly the same.
|
|
|
- if (type.getCanonicalType() == init->getType().getCanonicalType()) {
|
|
|
+ if (type.getCanonicalType() ==
|
|
|
+ init->getAstResultType().getCanonicalType()) {
|
|
|
initializers.pop_back();
|
|
|
- return theEmitter.loadIfGLValue(init);
|
|
|
+ return init;
|
|
|
}
|
|
|
|
|
|
// Otherwise, if the next initializer is an array, it is not of the same
|
|
@@ -453,17 +445,15 @@ InitListHandler::createInitForSamplerImageType(QualType type,
|
|
|
while (tryToSplitStruct() || tryToSplitConstantArray())
|
|
|
;
|
|
|
|
|
|
- const Expr *init = initializers.back();
|
|
|
+ auto *init = initializers.back();
|
|
|
initializers.pop_back();
|
|
|
|
|
|
- if (init->getType().getCanonicalType() != type.getCanonicalType()) {
|
|
|
- init->dump();
|
|
|
- emitError("cannot cast initializer type %0 into variable type %1",
|
|
|
- init->getLocStart())
|
|
|
- << init->getType() << type;
|
|
|
+ if (init->getAstResultType().getCanonicalType() != type.getCanonicalType()) {
|
|
|
+ emitError("Cannot cast initializer type %0 into variable type %1", srcLoc)
|
|
|
+ << init->getAstResultType() << type;
|
|
|
return nullptr;
|
|
|
}
|
|
|
- return theEmitter.loadIfGLValue(init);
|
|
|
+ return init;
|
|
|
}
|
|
|
|
|
|
} // end namespace spirv
|