Hello –
I’ve been trying to use the Sema object to generate implicit definitions, e.g. default constructors, destructors, etc, in a tool that I have but I’m running into some issues. The code that I have is a DeclVisitor with the following for the CXXRecord case.
void VisitCXXRecordDecl(CXXRecordDecl *decl, bool is_specialization) {
if (not(decl->isImplicit() or decl->isAnonymousStructOrUnion())) {
ci_->getSema().ForceDeclarationOfImplicitMembers(decl);
}
// …
}
This works great, and always works to get me constructor definitions with empty bodies but marked as default.
To generate the bodies, I have (roughly) the following code for constructors, destructors, and methods:
if (not decl->getBody() && decl->isDefaulted()) {
if (decl->isMoveAssignmentOperator()) {
ci_->getSema().DefineImplicitMoveAssignment(decl->getLocation(), decl);
} else if (decl->isCopyAssignmentOperator()) {
ci_->getSema().DefineImplicitCopyAssignment(decl->getLocation(), decl);
}
}
In most cases, this seems to do the trick, but when the implementation of the operator uses something like memcpy I get a segfault (stack trace below) due (it seems) to the fact that TUScope is null when my code runs.
#0 0x00007ffff5ff733a in clang::Sema::PushOnScopeChains(clang::NamedDecl*, clang::Scope*, bool) () from /usr/lib/libclang-cpp.so.10
#1 0x00007ffff601dc18 in clang::Sema::LazilyCreateBuiltin(clang::IdentifierInfo*, unsigned int, clang::Scope*, bool, clang::SourceLocation) () from /usr/lib/libclang-cpp.so.10
#2 0x00007ffff63599ac in clang::Sema::LookupBuiltin(clang::LookupResult&) () from /usr/lib/libclang-cpp.so.10
#3 0x00007ffff636e713 in clang::Sema::LookupName(clang::LookupResult&, clang::Scope*, bool) () from /usr/lib/libclang-cpp.so.10
#4 0x00007ffff61512e4 in ?? () from /usr/lib/libclang-cpp.so.10
#5 0x00007ffff6151643 in ?? () from /usr/lib/libclang-cpp.so.10
#6 0x00007ffff6159481 in clang::Sema::DefineImplicitCopyAssignment(clang::SourceLocation, clang::CXXMethodDecl*) () from /usr/lib/libclang-cpp.so.10
I can avoid this problem if I put the preprocessor in “incremental processing mode” using enableIncrementalProcessing()
from BeginSourceFileAction in my ASTFrontendAction, but doing this causes clang to not generate the bodies of template specializations. I assume that this is because you can’t generate specializations until you have the complete module which makes sense.
Is there some way that I can get both of these, i.e. generate all implicit declarations with their bodies and get template specializations? Perhaps by using Sema to generate the bodies and then somehow finishing the file to get clang to generate the specializations? Or maybe I can manually call something in Sema to generate the bodies of the templates?
Thanks in advance.