Biohazrd icon indicating copy to clipboard operation
Biohazrd copied to clipboard

Add support for records nested within implicit template specializations

Open PathogenDavid opened this issue 3 years ago • 1 comments

Right now records nested within template specializations are not properly translated. The currently handling is broken in different ways depending on whether the template was late-instantiated.

template<typename T> class MyTemplate
{
public:
    T Field1;
    T Field2;

    T Method(T x)
    {
        return x;
    }

    struct MyStruct
    {
        T NestedField;
    };
};

typedef MyTemplate<int> MyTemplateInt;
typedef MyTemplate<short> MyTemplateShort;

int Test(MyTemplate<int>::MyStruct& s)
{
    return s.NestedField;
}

MyTemplate<int>::MyStruct will be missing from the translation. The MyStruct which is enumerated when translating MyTemplate<int> has a definition, but the enumerated cursor is not considered to be the actual definition. This causes it to be skipped by this logic in TranslationUnitParser. (The intent here is that the definition will be encountered later on and we'll translate it then. Since this record is only implicitly defined it will never be countered.)

The ideal fix here would be to see if Clang somehow marks this as a declaration which was created by an implicit template instantiation and in that scenario we just use the definition. (And maybe keep track of a HashSet to assert we aren't double-translating these types somehow*


MyTemplate<short>::MyStruct will be present, but it will be a TranslatedUndefinedRecord since the cursor has no definition. Additionally, the raw child declarations list appears to be empty. It seems like there's an extra level of laziness for types nested within a templated type. The fix for this might be similar to the fix for https://github.com/InfectedLibraries/Biohazrd/issues/153


*Possible test case to verify this bit:

template<typename T> class MyTemplate
{
public:
    struct MyStruct;

    T Method(MyStruct& s)
    {
        return s.NestedField;
    }

    struct MyStruct
    {
        T NestedField;
    };
};

PathogenDavid avatar Mar 28 '21 13:03 PathogenDavid

Appended title to clarify that this does not happen with explicit template instantiations. (This is covered by TemplateTests.ExplicitTemplateSpecialization)

The issues outlined in this issue should be covered by TemplateTests.ImplicitTemplateSpecialization_NestedRecord

PathogenDavid avatar Mar 28 '21 13:03 PathogenDavid