[cfe-dev] clang and gcc implement __PRETTY_FUNCTION__ differently

Douglas Gregor dgregor at apple.com
Tue Mar 13 13:16:45 PDT 2012


On Mar 13, 2012, at 6:23 AM, Nikola Smiljanic wrote:

> Here's another shot at this. This version will print template parameter names instead of actual types used in the instantiation. It covers return type, function parameters and parameters from the enclosing class/es.

Thanks for working on this. I have a few comments:

-        FD->getParamDecl(i)->getType().getAsStringInternal(Param, Policy);
+        QualType Type =	FD->getParamDecl(i)->getType();
+        if (const SubstTemplateTypeParmType *TTP
+                                    = dyn_cast<SubstTemplateTypeParmType>(Type))
+          TTP->getReplacedParameter()->desugar()
+                                            .getAsStringInternal(Param, Policy);
+        else
+          Type.getAsStringInternal(Param, Policy);
         POut << Param;

This is only going to work when the function parameter type is a template parameter type (T), but not a compound type involving T (e.g, T*). You'll want to find a solution that works recursively.

> Note that we don't show template parameter names when it comes to classes:
> 
> ClassTemplate<int>::memberFunction(T) [T = int] // GCC would show ClassTemplate<T>
> 
> This part of the string is obtained by calling FunctionDecl::getQualifiedNameAsString. Showing template parameter names like GCC would require duplicating most of the code in getQualifiedNameAsString without any significant gain.

Or adding flags to the existing type/nested-name-specifier printers to print the template parameters rather than the substituted types.

> I added a few tests to test\CodeGenCXX\predefined-expr.cpp that cover:
>  - template parameter as return type
>  - function template with two template parameters
>  - template parameter that doesn't show up in the function declaration (used only inside the body)
>  - nested classes with template parameters
>  - non type template parameter
>  - template template parameter

Cool, thanks for being thorough. I suggest adding some more tests with compound types.

> There is also a FIXME that says: "Maybe this should use DeclPrinter with a special "print predefined expr" policy instead". I'm not really sure what this means as I am not familiar with printers and policies, but if you think it makes sense just point me in the right direction and I'll be more than happy to rework the code.


The policy it is referring to is the PrintingPolicy struct, defined in PrettyPrinter.h. You could add a new flag there that says "don't replace a substituted template parameter with its replacement", and teach the code in TypePrinter.cpp to obey that flag. Your code, above, is already passing a policy through (the Policy) parameter, so it would be fairly easy to tweak it at the source. That approach should be both simpler and more robust.

There's a completely different approach you could take: if the function is instantiated from a template, you could retrieve the template from which it was instantiated and print *that* type, along with the mapping from template parameters to template arguments. That way, you don't have to change type printing at all, because what you're printing still has the template parameters in place.

	- Doug



More information about the cfe-dev mailing list