forked from OSchip/llvm-project
Name mangling for class template specializations and template arguments.
llvm-svn: 71861
This commit is contained in:
parent
4579b76ff6
commit
f6e9ece507
|
@ -19,6 +19,7 @@
|
|||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
@ -67,6 +68,9 @@ namespace {
|
|||
void mangleExpression(Expr *E);
|
||||
void mangleCXXCtorType(CXXCtorType T);
|
||||
void mangleCXXDtorType(CXXDtorType T);
|
||||
|
||||
void mangleTemplateArgumentList(const TemplateArgumentList &L);
|
||||
void mangleTemplateArgument(const TemplateArgument &A);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -290,8 +294,13 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC) {
|
|||
|
||||
if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(DC))
|
||||
mangleSourceName(Namespace->getIdentifier());
|
||||
else if (const RecordDecl *Record = dyn_cast<RecordDecl>(DC))
|
||||
mangleSourceName(Record->getIdentifier());
|
||||
else if (const RecordDecl *Record = dyn_cast<RecordDecl>(DC)) {
|
||||
if (const ClassTemplateSpecializationDecl *D =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
|
||||
mangleType(QualType(D->getTypeForDecl(), 0));
|
||||
} else
|
||||
mangleSourceName(Record->getIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -571,6 +580,12 @@ void CXXNameMangler::mangleType(const TagType *T) {
|
|||
mangleName(T->getDecl()->getTypedefForAnonDecl());
|
||||
else
|
||||
mangleName(T->getDecl());
|
||||
|
||||
// If this is a class template specialization, mangle the template
|
||||
// arguments.
|
||||
if (ClassTemplateSpecializationDecl *Spec
|
||||
= dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl()))
|
||||
mangleTemplateArgumentList(Spec->getTemplateArgs());
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleType(const ArrayType *T) {
|
||||
|
@ -649,6 +664,53 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
|
|||
}
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleTemplateArgumentList(const TemplateArgumentList &L) {
|
||||
// <template-args> ::= I <template-arg>+ E
|
||||
Out << "I";
|
||||
|
||||
for (unsigned i = 0, e = L.size(); i != e; ++i) {
|
||||
const TemplateArgument &A = L[i];
|
||||
|
||||
mangleTemplateArgument(A);
|
||||
}
|
||||
|
||||
Out << "E";
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleTemplateArgument(const TemplateArgument &A) {
|
||||
// <template-arg> ::= <type> # type or template
|
||||
// ::= X <expression> E # expression
|
||||
// ::= <expr-primary> # simple expressions
|
||||
// ::= I <template-arg>* E # argument pack
|
||||
// ::= sp <expression> # pack expansion of (C++0x)
|
||||
switch (A.getKind()) {
|
||||
default:
|
||||
assert(0 && "Unknown template argument kind!");
|
||||
case TemplateArgument::Type:
|
||||
mangleType(A.getAsType());
|
||||
break;
|
||||
case TemplateArgument::Integral:
|
||||
// <expr-primary> ::= L <type> <value number> E # integer literal
|
||||
|
||||
Out << 'L';
|
||||
|
||||
mangleType(A.getIntegralType());
|
||||
|
||||
const llvm::APSInt *Integral = A.getAsIntegral();
|
||||
if (A.getIntegralType()->isBooleanType()) {
|
||||
// Boolean values are encoded as 0/1.
|
||||
Out << (Integral->getBoolValue() ? '1' : '0');
|
||||
} else {
|
||||
if (Integral->isNegative())
|
||||
Out << 'n';
|
||||
Integral->abs().print(Out, false);
|
||||
}
|
||||
|
||||
Out << 'E';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
/// \brief Mangles the name of the declaration D and emits that name
|
||||
/// to the given output stream.
|
||||
|
|
|
@ -49,5 +49,31 @@ namespace N { int f(int, int) { static int b; return b; } }
|
|||
// RUN: grep "_ZGVZN1N1gEvE1a =" %t | count 1 &&
|
||||
namespace N { int h(); void g() { static int a = h(); } }
|
||||
|
||||
// RUN: grep "_Z1fno" %t | count 1
|
||||
// RUN: grep "_Z1fno" %t | count 1 &&
|
||||
void f(__int128_t, __uint128_t) { }
|
||||
|
||||
template <typename T> struct S1 {};
|
||||
|
||||
// RUN: grep "_Z1f2S1IiE" %t | count 1 &&
|
||||
void f(S1<int>) {}
|
||||
|
||||
// RUN: grep "_Z1f2S1IdE" %t | count 1 &&
|
||||
void f(S1<double>) {}
|
||||
|
||||
template <int N> struct S2 {};
|
||||
// RUN: grep "_Z1f2S2ILi100EE" %t | count 1 &&
|
||||
void f(S2<100>) {}
|
||||
|
||||
// RUN: grep "_Z1f2S2ILin100EE" %t | count 1 &&
|
||||
void f(S2<-100>) {}
|
||||
|
||||
template <bool B> struct S3 {};
|
||||
|
||||
// RUN: grep "_Z1f2S3ILb1EE" %t | count 1 &&
|
||||
void f(S3<true>) {}
|
||||
|
||||
// RUN: grep "_Z1f2S3ILb0EE" %t | count 1 &&
|
||||
void f(S3<false>) {}
|
||||
|
||||
// RUN: grep "_Z2f22S3ILb1EE" %t | count 1
|
||||
void f2(S3<100>) {}
|
||||
|
|
Loading…
Reference in New Issue