[cfe-dev] Partial Template Specialization

Manuel Klimek klimek at google.com
Sat Apr 7 07:41:34 PDT 2012


On Fri, Apr 6, 2012 at 12:12 AM, Yang Chen <chenyang at cs.utah.edu> wrote:
> Douglas Gregor wrote:
>> On Apr 5, 2012, at 2:16 PM, Yang Chen <chenyang at cs.utah.edu> wrote:
>>
>>
>>> Hi,
>>>
>>> I am writing a pass using ASTConsumer. I find that seems some
>>> declarations of partial template specializations  are missing from
>>> TranslationUnitDecl. For example, given the simple code below:
>>>
>>> template<bool, typename>
>>> struct AAA { };
>>>
>>> template<typename T>
>>> struct AAA<true, T>
>>> { };
>>>
>>> I get the following result dumped from MyPass::HandleTranslationUnit()
>>> function, where MyPass is inherited from ASTConsumer.
>>>
>>> (gdb) p Ctx.getTranslationUnitDecl()->dump()
>>> struct __va_list_tag {
>>>    unsigned int gp_offset;
>>>    unsigned int fp_offset;
>>>    void *overflow_arg_area;
>>>    void *reg_save_area;
>>> };
>>> typedef struct __va_list_tag __va_list_tag;
>>> template <typename > struct AAA {
>>> };
>>> $1 = void
>>>
>>> In the above output, only template class AAA is presented, but the
>>> partial template specialization is missing.
>>>
>>
>> Yeah, the AST should probably have the class template partial specializations listed here.
>>
>>
>>> Is this an expected behavior, or is it a Clang bug? Sorry for my vague
>>> description. Hopefully I am not missing anything.
>>>
>>
>> You can retrieve class template partial specializations of a ClassTemplateDecl using getPartialSpecializations().
>>
>>       - Doug
>>
>
> Doug,
>
> Thanks for the reply.
>
> I tried getPartialSpecializations() on ClassTemplateDecl in the above
> example, but it returns an empty SmallVector to me, shown as below:
> (MyVisitor is an inheritance from RecursiveASTVisitor):
>
> bool MyVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D)
> {
>  llvm::SmallVector<ClassTemplatePartialSpecializationDecl*, 5> ParSpecs;
>  D->getPartialSpecializations(ParSpecs);
>  unsigned Sz = ParSpecs.size();
>  return true;
> }
>
> And from gdb:
>
> Breakpoint 1, MyVisitor::VisitClassTemplateDecl (this=0x1c340f0,
> D=0x1c5ec90) at MyClass.cpp:103
> ... [skipped]
> (gdb) p Sz
> $1 = 0
> (gdb) p D->dump()
> template <typename > struct AAA {
> }$2 = void
>
> One more thing is that I assume
> VisitClassTemplatePartialSpecializationDecl should capture the partial
> template specialization above, but it doesn't.

You can control some of what the RAV visits by implementing methods
like shouldVisitTemplateInstantiations. I think that should not make a
difference in your example, as yours is an explicit specialization and
the RAV tries to always visit user-written code, but it might as well
be a bug in the RAV. I'm working on adding a unit test on the RAV so
we can find and fix problems like yours more easily.

Cheers,
/Manuel




More information about the cfe-dev mailing list