How to resolve debug info forward types

Before metadata was separated from values, I could create a debug info forward
declaration and eventually resolve it using LLVMReplaceAllUsesWith in core.h.
Now, I can't figure out how to resolve it. I can find no function that seems
to do this. My one wild guess that giving the forward decl and the resolving
decl the same UniqueId might do it is not working.

I am currently using 3.6.1, but I see nothing the voluminous diff of DIBuilder
from 3.6.1 to 3.7.1 that looks like it has anything to do with this.

There are replaceable MD nodes - you could check how Clang does this when encountering a declaration, then a definition:

struct foo;
void f(foo *) {
}
struct foo {
};
void g(foo) {
}

Should exercise “Build a declaration”, “build a definition”, “replace declaration with definition”

It’s now a multi-stage process.

First, there is a difference between a permanent forward declaration (i.e. the actual definition is in a different file) and a temporary forward declaration (i.e. it will appear later in the same file).

To create a permanent forward declaration:

DICompositeType *result = m_DIBuilder->createForwardDecl(
dwarf::DW_TAG_structure_type,
name,
m_DICompileUnit,
file,
loc.m_Line);

To create a temporary forward declaration:

DICompositeType *result = m_DIBuilder->createReplaceableCompositeType(
dwarf::DW_TAG_structure_type,
name,
m_DICompileUnit,
file,
loc.m_Line);

And then, once the final value of the temporary is known (and you GOTTA do this step otherwise you get an assert):

DICompositeType *result = m_DIBuilder->createStructType(
m_DICompileUnit,
name,
file,
loc.m_Line,
sizeOf(actual) * 8, alignOf(actual) * 8,
0, nullptr, elts);

it = m_TmpStructDI.find(name);
if (it != m_TmpStructDI.end()) {
MDNode node = / the result from createReplaceableCompositeType earlier */
llvm::TempMDNode fwd_decl(node);

m_DIBuilder->replaceTemporary(std::move(fwd_decl), result);

You will need to keep a map of outstanding temporary forward declarations to do this.

Thanks, this got me going. I had to do things a bit differently for 3.6.1.
But the body of DIBuilder::replaceTemporary of 3.7.1 led me to what I need
in MDNodeFwdDecl::replaceAllUsesWith, in Metadata.h of 3.6.1.