Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Null access violation when using InstantiateTemplate with variadic class template #305

Open
deadlocklogic opened this issue Jun 5, 2024 · 7 comments
Labels

Comments

@deadlocklogic
Copy link

I am using the snippet: of the function static Decl* InstantiateTemplate(TemplateDecl* TemplateD, ArrayRef<TemplateArgument> TemplateArgs, Sema& S). It works unless the class template is variadic.
Consider:

template <typename... T>
class ClassTemplate
{
};

Now when analyzing any instantiations of this template like for example: ClassTemplate<> I obtain an ClassTemplateSpecializationDecl CTSD with CTSD->getSpecializationKind() == clang::TemplateSpecializationKind::TSK_Undeclared.
Now when trying to instantiate this class template with:
InstantiateTemplate(CTSD->getSpecializedTemplate(), CTSD->getTemplateInstantiationArgs().asArray(), CI.getSema());
I get null access violation exception.
Any ideas?
Thanks.

@vgvassilev
Copy link
Contributor

We have not added support for variadic templates yet. It was at some point in @maximusron's radar.

@aaronj0
Copy link
Collaborator

aaronj0 commented Jun 10, 2024

@deadlocklogic I think we shouldn't be constructing the TemplateArgumentListInfo ourselves, can you try using this function :

static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
TemplateArgumentListInfo& TLI, Sema& S) {
without using .asArray() for the args. If it doesn't work I was wondering if we should extract the clang::PackExpansionType and use the pattern, but looks like Sema::DeduceTemplateArguments does that already... @vgvassilev any idea what would be a good way to proceed here?

@vgvassilev
Copy link
Contributor

I think we need to check what clang does in these cases and try to replay it in CppInterOp.

@deadlocklogic
Copy link
Author

I solved my problem by unpacking template arguments when needed:

inline clang::Decl *InstantiateTemplate(clang::TemplateDecl *TemplateD,
                                        llvm::ArrayRef<clang::TemplateArgument> TemplateArgs, clang::Sema &S) {
  clang::TemplateArgumentListInfo TLI{};
  for (auto TA : TemplateArgs) {
    if (TA.getKind() == clang::TemplateArgument::ArgKind::Pack) {
      for (auto PTA : TA.getPackAsArray()) {
        TLI.addArgument(S.getTrivialTemplateArgumentLoc(PTA, clang::QualType(), clang::SourceLocation()));
      }
    } else {
      TLI.addArgument(S.getTrivialTemplateArgumentLoc(TA, clang::QualType(), clang::SourceLocation()));
    }
  }

  return InstantiateTemplate(TemplateD, TLI, S);
}

I don't know if there is a better solution.

@vgvassilev
Copy link
Contributor

Can you submit a PR with tests for this change?

@deadlocklogic
Copy link
Author

deadlocklogic commented Jun 10, 2024

Ok, I can submit a PR fixing the issue. I will try writing a test too.

Copy link
Contributor

github-actions bot commented Dec 4, 2024

This issue is stale because it has been open for 90 days with no activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants