Name mangling for class template specializations and template arguments.

llvm-svn: 71861
This commit is contained in:
Anders Carlsson 2009-05-15 16:09:15 +00:00
parent 4579b76ff6
commit f6e9ece507
2 changed files with 91 additions and 3 deletions

View File

@ -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.

View File

@ -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>) {}