mirror of https://github.com/microsoft/clang.git
Improve the printing of __PRETTY_FUNCTION__ more provide more
information and more closely match GCC's, from Nikola Smiljanic! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154430 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
316551f079
commit
abf65ce5dd
|
@ -399,21 +399,23 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
|
|||
}
|
||||
|
||||
PrintingPolicy Policy(Context.getLangOpts());
|
||||
|
||||
std::string Proto = FD->getQualifiedNameAsString(Policy);
|
||||
llvm::raw_string_ostream POut(Proto);
|
||||
|
||||
const FunctionType *AFT = FD->getType()->getAs<FunctionType>();
|
||||
const FunctionDecl *Decl = FD;
|
||||
if (const FunctionDecl* Pattern = FD->getTemplateInstantiationPattern())
|
||||
Decl = Pattern;
|
||||
const FunctionType *AFT = Decl->getType()->getAs<FunctionType>();
|
||||
const FunctionProtoType *FT = 0;
|
||||
if (FD->hasWrittenPrototype())
|
||||
FT = dyn_cast<FunctionProtoType>(AFT);
|
||||
|
||||
Proto += "(";
|
||||
POut << "(";
|
||||
if (FT) {
|
||||
llvm::raw_string_ostream POut(Proto);
|
||||
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
|
||||
for (unsigned i = 0, e = Decl->getNumParams(); i != e; ++i) {
|
||||
if (i) POut << ", ";
|
||||
std::string Param;
|
||||
FD->getParamDecl(i)->getType().getAsStringInternal(Param, Policy);
|
||||
Decl->getParamDecl(i)->getType().getAsStringInternal(Param, Policy);
|
||||
POut << Param;
|
||||
}
|
||||
|
||||
|
@ -422,16 +424,74 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
|
|||
POut << "...";
|
||||
}
|
||||
}
|
||||
Proto += ")";
|
||||
POut << ")";
|
||||
|
||||
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
|
||||
Qualifiers ThisQuals = Qualifiers::fromCVRMask(MD->getTypeQualifiers());
|
||||
if (ThisQuals.hasConst())
|
||||
Proto += " const";
|
||||
POut << " const";
|
||||
if (ThisQuals.hasVolatile())
|
||||
Proto += " volatile";
|
||||
POut << " volatile";
|
||||
RefQualifierKind Ref = MD->getRefQualifier();
|
||||
if (Ref == RQ_LValue)
|
||||
POut << " &";
|
||||
else if (Ref == RQ_RValue)
|
||||
POut << " &&";
|
||||
}
|
||||
|
||||
typedef SmallVector<const ClassTemplateSpecializationDecl *, 8> SpecsTy;
|
||||
SpecsTy Specs;
|
||||
const DeclContext *Ctx = FD->getDeclContext();
|
||||
while (Ctx && isa<NamedDecl>(Ctx)) {
|
||||
const ClassTemplateSpecializationDecl *Spec
|
||||
= dyn_cast<ClassTemplateSpecializationDecl>(Ctx);
|
||||
if (Spec && !Spec->isExplicitSpecialization())
|
||||
Specs.push_back(Spec);
|
||||
Ctx = Ctx->getParent();
|
||||
}
|
||||
|
||||
std::string TemplateParams;
|
||||
llvm::raw_string_ostream TOut(TemplateParams);
|
||||
for (SpecsTy::reverse_iterator I = Specs.rbegin(), E = Specs.rend();
|
||||
I != E; ++I) {
|
||||
const TemplateParameterList *Params
|
||||
= (*I)->getSpecializedTemplate()->getTemplateParameters();
|
||||
const TemplateArgumentList &Args = (*I)->getTemplateArgs();
|
||||
assert(Params->size() == Args.size());
|
||||
for (unsigned i = 0, numParams = Params->size(); i != numParams; ++i) {
|
||||
StringRef Param = Params->getParam(i)->getName();
|
||||
if (Param.empty()) continue;
|
||||
TOut << Param << " = ";
|
||||
Args.get(i).print(Policy, TOut);
|
||||
TOut << ", ";
|
||||
}
|
||||
}
|
||||
|
||||
FunctionTemplateSpecializationInfo *FSI
|
||||
= FD->getTemplateSpecializationInfo();
|
||||
if (FSI && !FSI->isExplicitSpecialization()) {
|
||||
const TemplateParameterList* Params
|
||||
= FSI->getTemplate()->getTemplateParameters();
|
||||
const TemplateArgumentList* Args = FSI->TemplateArguments;
|
||||
assert(Params->size() == Args->size());
|
||||
for (unsigned i = 0, e = Params->size(); i != e; ++i) {
|
||||
StringRef Param = Params->getParam(i)->getName();
|
||||
if (Param.empty()) continue;
|
||||
TOut << Param << " = ";
|
||||
Args->get(i).print(Policy, TOut);
|
||||
TOut << ", ";
|
||||
}
|
||||
}
|
||||
|
||||
TOut.flush();
|
||||
if (!TemplateParams.empty()) {
|
||||
// remove the trailing comma and space
|
||||
TemplateParams.resize(TemplateParams.size() - 2);
|
||||
POut << " [" << TemplateParams << "]";
|
||||
}
|
||||
|
||||
POut.flush();
|
||||
|
||||
if (!isa<CXXConstructorDecl>(FD) && !isa<CXXDestructorDecl>(FD))
|
||||
AFT->getResultType().getAsStringInternal(Proto, Policy);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
|
||||
|
||||
// CHECK: store i32 49, i32* %size
|
||||
// CHECK: store i32 52, i32* %size
|
||||
// CHECK: store i32 59, i32* %size
|
||||
// CHECK: store i32 65, i32* %size
|
||||
template<typename T>
|
||||
class TemplateClass {
|
||||
public:
|
||||
|
@ -10,8 +10,8 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// CHECK: store i32 27, i32* %size
|
||||
// CHECK: store i32 30, i32* %size
|
||||
// CHECK: store i32 35, i32* %size
|
||||
// CHECK: store i32 38, i32* %size
|
||||
template<typename T>
|
||||
void functionTemplate(T t) {
|
||||
int size = sizeof(__PRETTY_FUNCTION__);
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - | FileCheck %s
|
||||
|
||||
// CHECK: private unnamed_addr constant [15 x i8] c"externFunction\00"
|
||||
// CHECK: private unnamed_addr constant [26 x i8] c"void NS::externFunction()\00"
|
||||
// CHECK: private unnamed_addr constant [49 x i8] c"void functionTemplateExplicitSpecialization(int)\00"
|
||||
|
||||
// CHECK: private unnamed_addr constant [95 x i8] c"void SpecializedClassTemplate<char>::memberFunctionTemplate(T, U) const [T = char, U = double]\00"
|
||||
// CHECK: private unnamed_addr constant [85 x i8] c"void SpecializedClassTemplate<int>::memberFunctionTemplate(int, U) const [U = float]\00"
|
||||
// CHECK: private unnamed_addr constant [57 x i8] c"void NonTypeTemplateParam<42>::size() const [Count = 42]\00"
|
||||
// CHECK: private unnamed_addr constant [122 x i8] c"static void ClassWithTemplateTemplateParam<char, NS::ClassTemplate>::staticMember() [T = char, Param = NS::ClassTemplate]\00"
|
||||
// CHECK: private unnamed_addr constant [106 x i8] c"void OuterClass<int *>::MiddleClass::InnerClass<float>::memberFunction(T, U) const [T = int *, U = float]\00"
|
||||
// CHECK: private unnamed_addr constant [65 x i8] c"void functionTemplateWithUnnamedTemplateParameter(T) [T = float]\00"
|
||||
|
||||
// CHECK: private unnamed_addr constant [60 x i8] c"void functionTemplateExplicitSpecialization(T) [T = double]\00"
|
||||
// CHECK: private unnamed_addr constant [52 x i8] c"T *functionTemplateWithCompoundTypes(T *) [T = int]\00"
|
||||
// CHECK: private unnamed_addr constant [54 x i8] c"T functionTemplateWithTemplateReturnType() [T = char]\00"
|
||||
// CHECK: private unnamed_addr constant [57 x i8] c"void functionTemplateWithoutParameterList() [T = double]\00"
|
||||
// CHECK: private unnamed_addr constant [62 x i8] c"void functionTemplateWithTwoParams(T, U) [T = int, U = float]\00"
|
||||
|
||||
// CHECK: private unnamed_addr constant [22 x i8] c"classTemplateFunction\00"
|
||||
// CHECK: private unnamed_addr constant [60 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction()\00"
|
||||
// CHECK: private unnamed_addr constant [53 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction()\00"
|
||||
// CHECK: private unnamed_addr constant [77 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction() [T = NS::Base *]\00"
|
||||
// CHECK: private unnamed_addr constant [63 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction() [T = int]\00"
|
||||
|
||||
// CHECK: private unnamed_addr constant [18 x i8] c"functionTemplate1\00"
|
||||
// CHECK: private unnamed_addr constant [45 x i8] c"void NS::Base::functionTemplate1(NS::Base *)\00"
|
||||
// CHECK: private unnamed_addr constant [38 x i8] c"void NS::Base::functionTemplate1(int)\00"
|
||||
// CHECK: private unnamed_addr constant [53 x i8] c"void NS::Base::functionTemplate1(T) [T = NS::Base *]\00"
|
||||
// CHECK: private unnamed_addr constant [46 x i8] c"void NS::Base::functionTemplate1(T) [T = int]\00"
|
||||
|
||||
// CHECK: private unnamed_addr constant [23 x i8] c"anonymousUnionFunction\00"
|
||||
// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous union>::anonymousUnionFunction()\00"
|
||||
|
@ -31,6 +45,10 @@
|
|||
// CHECK: private unnamed_addr constant [16 x i8] c"virtualFunction\00"
|
||||
// CHECK: private unnamed_addr constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00"
|
||||
|
||||
// CHECK: private unnamed_addr constant [21 x i8] c"refQualifiedFunction\00"
|
||||
// CHECK: private unnamed_addr constant [41 x i8] c"void NS::Base::refQualifiedFunction() &&\00"
|
||||
// CHECK: private unnamed_addr constant [40 x i8] c"void NS::Base::refQualifiedFunction() &\00"
|
||||
|
||||
// CHECK: private unnamed_addr constant [22 x i8] c"constVolatileFunction\00"
|
||||
// CHECK: private unnamed_addr constant [54 x i8] c"void NS::Base::constVolatileFunction() const volatile\00"
|
||||
|
||||
|
@ -78,6 +96,8 @@
|
|||
// CHECK: private unnamed_addr constant [19 x i8] c"localClassFunction\00"
|
||||
// CHECK: private unnamed_addr constant [59 x i8] c"void NS::localClass(int)::LocalClass::localClassFunction()\00"
|
||||
|
||||
|
||||
|
||||
int printf(const char * _Format, ...);
|
||||
|
||||
class ClassInTopLevelNamespace {
|
||||
|
@ -203,11 +223,23 @@ public:
|
|||
printf("__FUNCTION__ %s\n", __FUNCTION__);
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
void refQualifiedFunction() & {
|
||||
printf("__func__ %s\n", __func__);
|
||||
printf("__FUNCTION__ %s\n", __FUNCTION__);
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
void refQualifiedFunction() && {
|
||||
printf("__func__ %s\n", __func__);
|
||||
printf("__FUNCTION__ %s\n", __FUNCTION__);
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
};
|
||||
|
||||
class Derived : public Base {
|
||||
public:
|
||||
// Virtual function without being explicitally written.
|
||||
// Virtual function without being explicitly written.
|
||||
void virtualFunction() {
|
||||
printf("__func__ %s\n", __func__);
|
||||
printf("__FUNCTION__ %s\n", __FUNCTION__);
|
||||
|
@ -294,6 +326,116 @@ extern void externFunction() {
|
|||
|
||||
} // end NS namespace
|
||||
|
||||
// additional tests for __PRETTY_FUNCTION__
|
||||
template <typename T, typename U>
|
||||
void functionTemplateWithTwoParams(T, U)
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void functionTemplateWithoutParameterList()
|
||||
{
|
||||
T t = T();
|
||||
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T functionTemplateWithTemplateReturnType()
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
|
||||
return T();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T * functionTemplateWithCompoundTypes(T a[])
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void functionTemplateExplicitSpecialization(T t)
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
template <>
|
||||
void functionTemplateExplicitSpecialization<int>(int i)
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
template <typename, typename T>
|
||||
void functionTemplateWithUnnamedTemplateParameter(T t)
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class OuterClass
|
||||
{
|
||||
public:
|
||||
class MiddleClass
|
||||
{
|
||||
public:
|
||||
template <typename U>
|
||||
class InnerClass
|
||||
{
|
||||
public:
|
||||
void memberFunction(T x, U y) const
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T, template <typename> class Param = NS::ClassTemplate>
|
||||
class ClassWithTemplateTemplateParam
|
||||
{
|
||||
public:
|
||||
static void staticMember()
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
};
|
||||
|
||||
template <int Count>
|
||||
class NonTypeTemplateParam
|
||||
{
|
||||
public:
|
||||
void size() const
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class SpecializedClassTemplate
|
||||
{
|
||||
public:
|
||||
template <typename U>
|
||||
void memberFunctionTemplate(T t, U u) const
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class SpecializedClassTemplate<int>
|
||||
{
|
||||
public:
|
||||
template <typename U>
|
||||
void memberFunctionTemplate(int i, U u) const
|
||||
{
|
||||
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
ClassInAnonymousNamespace anonymousNamespace;
|
||||
anonymousNamespace.anonymousNamespaceFunction();
|
||||
|
@ -319,6 +461,8 @@ int main() {
|
|||
b.constFunction();
|
||||
b.volatileFunction();
|
||||
b.constVolatileFunction();
|
||||
b.refQualifiedFunction();
|
||||
NS::Base().refQualifiedFunction();
|
||||
|
||||
NS::Derived d;
|
||||
d.virtualFunction();
|
||||
|
@ -345,5 +489,29 @@ int main() {
|
|||
|
||||
NS::externFunction();
|
||||
|
||||
// additional tests for __PRETTY_FUNCTION__
|
||||
|
||||
functionTemplateWithTwoParams(0, 0.0f);
|
||||
functionTemplateWithoutParameterList<double>();
|
||||
functionTemplateWithTemplateReturnType<char>();
|
||||
int array[] = { 1, 2, 3 };
|
||||
functionTemplateWithCompoundTypes(array);
|
||||
functionTemplateExplicitSpecialization(0);
|
||||
functionTemplateExplicitSpecialization(0.0);
|
||||
functionTemplateWithUnnamedTemplateParameter<int, float>(0.0f);
|
||||
|
||||
OuterClass<int *>::MiddleClass::InnerClass<float> omi;
|
||||
omi.memberFunction(0, 0.0f);
|
||||
|
||||
ClassWithTemplateTemplateParam<char>::staticMember();
|
||||
|
||||
NonTypeTemplateParam<42> ntt;
|
||||
ntt.size();
|
||||
|
||||
SpecializedClassTemplate<int> sct1;
|
||||
sct1.memberFunctionTemplate(0, 0.0f);
|
||||
SpecializedClassTemplate<char> sct2;
|
||||
sct2.memberFunctionTemplate('0', 0.0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue