[cfe-dev] clang and gcc implement __PRETTY_FUNCTION__ differently
Douglas Gregor
dgregor at apple.com
Thu Mar 15 12:43:02 PDT 2012
On Mar 15, 2012, at 3:46 AM, Nikola Smiljanic wrote:
> That did the trick, but I don't understand why, what is the difference
> between getTemplatedDecl (underlying template declaration) and
> getInstantiatedFromMemberTemplate (previous declaration of this
> template). And then there is also getPreviousDecl (previous
> declaration of this function template). Doxygen comments aren't very
> revealing here, and I'm sure that knowing the terminology from the
> standard would help, but can somebody please explain.
>
> Anyway this is the new patch. Two things to note here:
Much improved!
> 1. Since I don't really understand this special case I'm not sure if
> my logic for handling it is OK (the tests that I have all pass). I'm
> talking about the part inside (TK ==
> TK_FunctionTemplateSpecialization) branch.
+ if (TK == FunctionDecl::TK_FunctionTemplateSpecialization) {
+ FunctionTemplateDecl *Primary = FD->getPrimaryTemplate();
+ FunctionTemplateDecl *TemplatedDecl
+ = Primary->getInstantiatedFromMemberTemplate();
+ Decl = TemplatedDecl ? TemplatedDecl->getTemplatedDecl()
+ : Primary->getTemplatedDecl();
+ }
+ else if (TK == FunctionDecl::TK_MemberSpecialization)
+ Decl = FD->getInstantiatedFromMemberFunction();
+
As John noted, if you want to get back to the original source, you'll need to make this a loop. Plus, you'll probably want to check if it was an explicit specialization and stop iterating at that point, since explicit specializations were written by the user (rather than instantiated).
+ typedef SmallVector<const ClassTemplateSpecializationDecl *, 8> SpecsTy;
+ SpecsTy Specs;
+ const DeclContext *Ctx = FD->getDeclContext();
+ while (Ctx && isa<NamedDecl>(Ctx)) {
+ if (const ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(Ctx))
+ Specs.push_back(Spec);
+ Ctx = Ctx->getParent();
+ }
There are a few cases here, too. For example, you could have a CXXRecordDecl that's an instantiation of a member class, e.g.,
template<typename T>
struct X {
struct Inner {
void f();
};
};
and you don't want to skip "Inner" in the printing.
> 2. I added the test for compound types and I noticed that pointer
> return type is printed like "T *func". I know that we prefer printing
> the asterisk like this when it comes to variables, but is this OK for
> function return type?
Yes.
- Doug
More information about the cfe-dev
mailing list