[cfe-dev] A question related to bug 5866.
Enea Zaffanella
zaffanella at cs.unipr.it
Thu May 27 15:44:46 PDT 2010
John McCall wrote:
> On May 26, 2010, at 4:44 AM, Enea Zaffanella wrote:
>
>> Hello.
>>
>> I was struggling against friend declarations of template function
>> specializations, i.e., something strongly related to the following
>> (resolved) bug:
>>
>> http://llvm.org/bugs/show_bug.cgi?id=5866
>>
>> The problem we have is the following: when visiting a friend declaration
>> such as the one used in the bug report above
>>
>> friend streamsize
>> __copy_streambufs_eof<>(__streambuf_type*,
>> __streambuf_type*, bool&);
>>
>> we call method getFriendDecl() and obtain a FunctionDecl*,
>> but when querying this pointer using method
>> bool FunctionDecl::isFunctionTemplateSpecialization()
>> the answer turns out to be negative.
>>
>> Is this a bug, or are we just calling the method above out of its
>> specification? Are there other ways to check if a friend declaration is
>> referring to a template function specialization?
>
> It sounds like a bug.
>
> John.
OK, I managed to obtain more info and better understand the issue.
Strictly speaking, it looks like the one above is not a real bug ...
The example is as follows:
=========
template <typename T> void foo(T);
template <typename T>
class C {
friend void foo<>(T);
};
=========
Here the FriendDecl is declaring a
"dependent function template specialization".
If I understand the ratio from clang documentation, since these are
dependent, they are not actual function template
specializations/instances, hence method
FunctionDecl::isFunctionTemplateSpecialization()
is allowed to return false and method
FunctionDecl::getTemplateSpecializationKind()
returns TSK_Undeclared.
The info I was looking for, i.e., the (empty) list of template
arguments, can be found by using method:
DependentFunctionTemplateSpecializationInfo*
getDependentSpecializationInfo()
As a side note ... we observed that there are several slightly different
ways of iterating on collections of TemplateArg and TemplateArgLoc
objects ... and the methods to retrieve these collections have slightly
different names, sometimes they return pointers, sometimes they return
references, etc. For instance:
In DependentFunctionTemplateSpecializationInfo we have:
unsigned getNumTemplateArgs() const;
const TemplateArgumentLoc& getTemplateArg(unsigned I) const;
In FunctionTemplateSpecializationInfo we have:
const TemplateArgumentList* TemplateArguments;
const TemplateArgumentListInfo* TemplateArgumentsAsWritten;
In ClassTemplateSpecializationDecl we have:
const TemplateArgumentList& getTemplateArgs() const
In ClassTemplatePartialSpecializationDecl we also have:
TemplateArgumentLoc* getTemplateArgsAsWritten() const;
unsigned getNumTemplateArgsAsWritten() const;
TemplateArgumentList has methods
unsigned size() const;
const TemplateArgument& operator[](unsigned Idx) const;
const TemplateArgument& get(unsigned Idx) const;
while TemplateArgumentListInfo has methods:
unsigned size() const;
const TemplateArgumentLoc& operator[](unsigned I) const;
const TemplateArgumentLoc* getArgumentArray() const;
It would be nicer if a more uniform naming scheme and a common iteration
pattern were available.
Cheers,
Enea.
More information about the cfe-dev
mailing list