Skip to content

Support for multiple classes with the same name. #4

@GasparVardanyan

Description

@GasparVardanyan

Hi! Please consider this example:

# include <iostream>

int main () {
	{
		struct A { int a = 1; };
		struct X : virtual A {};
		struct Y : A {};
		struct AA : X, Y {};

		AA aa; // { AA, X, virtual A, Y, A }
		// aa.A::a = 0; // error1
		aa.X::a = 1;
		aa.Y::a = 2;
		// aa.a = 3; // error2

		std::cout << aa.X::a << aa.Y::a << std::endl;
	}

	{
		struct A { int a = 10; };
		struct X : virtual A {};
		struct Y : virtual A {};
		struct AA : X, Y {};

		AA aa; // { AA, X, virtual A, Y }
		std::cout << aa.A::a << aa.X::a << aa.Y::a << aa.AA::a << aa.a << std::endl;
		aa.A::a = 0;
		std::cout << aa.A::a << aa.X::a << aa.Y::a << aa.AA::a << aa.a << std::endl;
		aa.X::a = 1;
		std::cout << aa.A::a << aa.X::a << aa.Y::a << aa.AA::a << aa.a << std::endl;
		aa.Y::a = 2;
		std::cout << aa.A::a << aa.X::a << aa.Y::a << aa.AA::a << aa.a << std::endl;
		aa.a = 3;
		std::cout << aa.A::a << aa.X::a << aa.Y::a << aa.AA::a << aa.a << std::endl;
	}
}

On the second AA struct classlayout.nvim shows the memory layout of the first AA struct.
I think the soulution is to find the index of the current class under the cursor in the array of all classes with the same name in the current file and then take the matching output of the same index.

But... we have another problem.
Consider this example:
main.cpp:

# include <iostream>

# include "test.h"

int main () {
	{
		struct A { int a = 10; };
		struct X : virtual A {};
		struct Y : virtual A {};
		struct AA : X, Y {};

		AA aa; // { AA, X, virtual A, Y }
		std::cout << aa.A::a << aa.X::a << aa.Y::a << aa.AA::a << aa.a << std::endl;
		aa.A::a = 0;
		std::cout << aa.A::a << aa.X::a << aa.Y::a << aa.AA::a << aa.a << std::endl;
		aa.X::a = 1;
		std::cout << aa.A::a << aa.X::a << aa.Y::a << aa.AA::a << aa.a << std::endl;
		aa.Y::a = 2;
		std::cout << aa.A::a << aa.X::a << aa.Y::a << aa.AA::a << aa.a << std::endl;
		aa.a = 3;
		std::cout << aa.A::a << aa.X::a << aa.Y::a << aa.AA::a << aa.a << std::endl;
	}
}

test.h:

void f () {
	{
		struct A { int a = 1; };
		struct X : virtual A {};
		struct Y : A {};
		struct AA : X, Y {};

		AA aa; // { AA, X, virtual A, Y, A }
		// aa.A::a = 0; // error1
		aa.X::a = 1;
		aa.Y::a = 2;
		// aa.a = 3; // error2
	}
}

Again classlayout.nvim returns the class layout of the first AA struct (from test.h) when we invoke it on the main.cpp's AA struct.

Things complicate a lot here but I think the simplest and easiest solution is to preprocess the file, take all class names, randomely generate a class name which doesn't exist in the preprocessed file (for example take the longest name and add a letter at the end of it (and don't forget about the Standard's class name length limits)), then copy the original file, replace the class name under the cursor with the randomely generated name, run clang -Xclang... on it, find the info of our new class in the output, replace back the name in the output and show 🙂

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions