|
@@ -1652,14 +1652,18 @@ SpirvEvalInfo SPIRVEmitter::processCall(const CallExpr *callExpr) {
|
|
llvm::SmallVector<SpirvEvalInfo, 4> args; // Evaluated arguments
|
|
llvm::SmallVector<SpirvEvalInfo, 4> args; // Evaluated arguments
|
|
|
|
|
|
if (const auto *memberCall = dyn_cast<CXXMemberCallExpr>(callExpr)) {
|
|
if (const auto *memberCall = dyn_cast<CXXMemberCallExpr>(callExpr)) {
|
|
- isNonStaticMemberCall =
|
|
|
|
- !cast<CXXMethodDecl>(memberCall->getCalleeDecl())->isStatic();
|
|
|
|
|
|
+ const auto *memberFn = cast<CXXMethodDecl>(memberCall->getCalleeDecl());
|
|
|
|
+ isNonStaticMemberCall = !memberFn->isStatic();
|
|
|
|
+
|
|
if (isNonStaticMemberCall) {
|
|
if (isNonStaticMemberCall) {
|
|
// For non-static member calls, evaluate the object and pass it as the
|
|
// For non-static member calls, evaluate the object and pass it as the
|
|
// first argument.
|
|
// first argument.
|
|
const auto *object = memberCall->getImplicitObjectArgument();
|
|
const auto *object = memberCall->getImplicitObjectArgument();
|
|
object = object->IgnoreParenNoopCasts(astContext);
|
|
object = object->IgnoreParenNoopCasts(astContext);
|
|
|
|
|
|
|
|
+ // Update counter variable associated with the implicit object
|
|
|
|
+ tryToAssignCounterVar(getOrCreateDeclForMethodObject(memberFn), object);
|
|
|
|
+
|
|
objectType = object->getType();
|
|
objectType = object->getType();
|
|
objectEvalInfo = doExpr(object);
|
|
objectEvalInfo = doExpr(object);
|
|
uint32_t objectId = objectEvalInfo;
|
|
uint32_t objectId = objectEvalInfo;
|
|
@@ -2817,6 +2821,9 @@ bool SPIRVEmitter::tryToAssignCounterVar(const DeclaratorDecl *dstDecl,
|
|
// the translation of the real definition may not be started yet.
|
|
// the translation of the real definition may not be started yet.
|
|
if (const auto *param = dyn_cast<ParmVarDecl>(dstDecl))
|
|
if (const auto *param = dyn_cast<ParmVarDecl>(dstDecl))
|
|
declIdMapper.createFnParamCounterVar(param);
|
|
declIdMapper.createFnParamCounterVar(param);
|
|
|
|
+ // For implicit objects of methods. Similar to the above.
|
|
|
|
+ else if (const auto *thisObject = dyn_cast<ImplicitParamDecl>(dstDecl))
|
|
|
|
+ declIdMapper.createFnParamCounterVar(thisObject);
|
|
|
|
|
|
// Handle AssocCounter#1 (see CounterVarFields comment)
|
|
// Handle AssocCounter#1 (see CounterVarFields comment)
|
|
if (const auto *dstPair = declIdMapper.getCounterIdAliasPair(dstDecl)) {
|
|
if (const auto *dstPair = declIdMapper.getCounterIdAliasPair(dstDecl)) {
|
|
@@ -2831,11 +2838,9 @@ bool SPIRVEmitter::tryToAssignCounterVar(const DeclaratorDecl *dstDecl,
|
|
}
|
|
}
|
|
|
|
|
|
// Handle AssocCounter#3
|
|
// Handle AssocCounter#3
|
|
- const auto *dstFields = declIdMapper.getCounterVarFields(dstDecl);
|
|
|
|
llvm::SmallVector<uint32_t, 4> srcIndices;
|
|
llvm::SmallVector<uint32_t, 4> srcIndices;
|
|
- const auto *srcDecl = getReferencedDef(
|
|
|
|
- collectArrayStructIndices(srcExpr, &srcIndices, /*rawIndex=*/true));
|
|
|
|
- const auto *srcFields = declIdMapper.getCounterVarFields(srcDecl);
|
|
|
|
|
|
+ const auto *dstFields = declIdMapper.getCounterVarFields(dstDecl);
|
|
|
|
+ const auto *srcFields = getIntermediateACSBufferCounter(srcExpr, &srcIndices);
|
|
|
|
|
|
if (dstFields && srcFields) {
|
|
if (dstFields && srcFields) {
|
|
if (!dstFields->assign(*srcFields, theBuilder, typeTranslator)) {
|
|
if (!dstFields->assign(*srcFields, theBuilder, typeTranslator)) {
|
|
@@ -2875,12 +2880,8 @@ bool SPIRVEmitter::tryToAssignCounterVar(const Expr *dstExpr,
|
|
// Handle AssocCounter#3 & AssocCounter#4
|
|
// Handle AssocCounter#3 & AssocCounter#4
|
|
llvm::SmallVector<uint32_t, 4> dstIndices;
|
|
llvm::SmallVector<uint32_t, 4> dstIndices;
|
|
llvm::SmallVector<uint32_t, 4> srcIndices;
|
|
llvm::SmallVector<uint32_t, 4> srcIndices;
|
|
- const auto *dstDecl = getReferencedDef(
|
|
|
|
- collectArrayStructIndices(dstExpr, &dstIndices, /*rawIndex=*/true));
|
|
|
|
- const auto *srcDecl = getReferencedDef(
|
|
|
|
- collectArrayStructIndices(srcExpr, &srcIndices, /*rawIndex=*/true));
|
|
|
|
- const auto *dstFields = declIdMapper.getCounterVarFields(dstDecl);
|
|
|
|
- const auto *srcFields = declIdMapper.getCounterVarFields(srcDecl);
|
|
|
|
|
|
+ const auto *srcFields = getIntermediateACSBufferCounter(srcExpr, &srcIndices);
|
|
|
|
+ const auto *dstFields = getIntermediateACSBufferCounter(dstExpr, &dstIndices);
|
|
|
|
|
|
if (dstFields && srcFields) {
|
|
if (dstFields && srcFields) {
|
|
return dstFields->assign(*srcFields, dstIndices, srcIndices, theBuilder,
|
|
return dstFields->assign(*srcFields, dstIndices, srcIndices, theBuilder,
|
|
@@ -2898,13 +2899,47 @@ SPIRVEmitter::getFinalACSBufferCounter(const Expr *expr) {
|
|
|
|
|
|
// AssocCounter#2: referencing some non-struct field
|
|
// AssocCounter#2: referencing some non-struct field
|
|
llvm::SmallVector<uint32_t, 4> indices;
|
|
llvm::SmallVector<uint32_t, 4> indices;
|
|
- if (const auto *decl = getReferencedDef(
|
|
|
|
- collectArrayStructIndices(expr, &indices, /*rawIndex=*/true)))
|
|
|
|
- return declIdMapper.getCounterIdAliasPair(decl, &indices);
|
|
|
|
|
|
+
|
|
|
|
+ const auto *base =
|
|
|
|
+ collectArrayStructIndices(expr, &indices, /*rawIndex=*/true);
|
|
|
|
+ const auto *decl =
|
|
|
|
+ (base && isa<CXXThisExpr>(base))
|
|
|
|
+ ? getOrCreateDeclForMethodObject(cast<CXXMethodDecl>(curFunction))
|
|
|
|
+ : getReferencedDef(base);
|
|
|
|
+ return declIdMapper.getCounterIdAliasPair(decl, &indices);
|
|
|
|
|
|
return nullptr;
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+const CounterVarFields *SPIRVEmitter::getIntermediateACSBufferCounter(
|
|
|
|
+ const Expr *expr, llvm::SmallVector<uint32_t, 4> *indices) {
|
|
|
|
+ const auto *base =
|
|
|
|
+ collectArrayStructIndices(expr, indices, /*rawIndex=*/true);
|
|
|
|
+ const auto *decl =
|
|
|
|
+ (base && isa<CXXThisExpr>(base))
|
|
|
|
+ // Use the decl we created to represent the implicit object
|
|
|
|
+ ? getOrCreateDeclForMethodObject(cast<CXXMethodDecl>(curFunction))
|
|
|
|
+ // Find the referenced decl from the original source code
|
|
|
|
+ : getReferencedDef(base);
|
|
|
|
+
|
|
|
|
+ return declIdMapper.getCounterVarFields(decl);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const ImplicitParamDecl *
|
|
|
|
+SPIRVEmitter::getOrCreateDeclForMethodObject(const CXXMethodDecl *method) {
|
|
|
|
+ const auto found = thisDecls.find(method);
|
|
|
|
+ if (found != thisDecls.end())
|
|
|
|
+ return found->second;
|
|
|
|
+
|
|
|
|
+ const std::string name = method->getName().str() + ".this";
|
|
|
|
+ // Create a new identifier to convey the name
|
|
|
|
+ auto &identifier = astContext.Idents.get(name);
|
|
|
|
+
|
|
|
|
+ return thisDecls[method] = ImplicitParamDecl::Create(
|
|
|
|
+ astContext, /*DC=*/nullptr, SourceLocation(), &identifier,
|
|
|
|
+ method->getThisType(astContext)->getPointeeType());
|
|
|
|
+}
|
|
|
|
+
|
|
SpirvEvalInfo
|
|
SpirvEvalInfo
|
|
SPIRVEmitter::processACSBufferAppendConsume(const CXXMemberCallExpr *expr) {
|
|
SPIRVEmitter::processACSBufferAppendConsume(const CXXMemberCallExpr *expr) {
|
|
const bool isAppend = expr->getNumArgs() == 1;
|
|
const bool isAppend = expr->getNumArgs() == 1;
|