How to get the base type of opaque pointer?

I would like to know what is the base type of a pointer in a structure definition.

For example the following code:

struct A
{
    int a;
    char b;
    long c;
};

class B{
public:
    A *a;
};

int main(){
    A a = {1,'a',1000};
    B b;
    b.a = &a;
}

It corresponds to the following IR:

%struct.A = type { i32, i8, i64 }
%class.B = type { ptr }

@__const.main.a = private unnamed_addr constant %struct.A { i32 1, i8 97, i64 1000 }, align 8

define dso_local noundef i32 @main() #0 {
  %1 = alloca %struct.A, align 8
  %2 = alloca %class.B, align 8
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %1, ptr align 8 @__const.main.a, i64 16, i1 false)
  %3 = getelementptr inbounds %class.B, ptr %2, i32 0, i32 0
  store ptr %1, ptr %3, align 8
  ret i32 0
}

declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1

attributes #0 = { mustprogress noinline norecurse nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }

I want to know how to determine at the IR level that the ptr of class B points to struct A? Is there an existing passes?

Can anyone help me?

The short answer is that such type information isn’t all that reliable
at the level of LLVM IR, and it is generally better to organize any
passes to not need to care about the details of a pointer other than
that it is a pointer (and its address space, for those targets where
address spaces are relevant, largely GPU targets).

Depending on your use case, a good enough answer may be to look for an
alloca of that struct type, track down getelementptr references to the
corresponding field, and see what the type of corresponding loads and
stores are and guess that it’s a reasonable default. But in general,
treating a ptr as void * (in C terms) with implicit bitcasts to the
appropriate type of any load or store instruction using that pointer is
generally the best default if you’re trying to turn opaque pointer IR
back into typed pointer IR.

1 Like

Thanks for the reply, I will try what you said!