diff options
author | Anders Carlsson <andersca@mac.com> | 2009-05-15 16:09:15 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-05-15 16:09:15 +0000 |
commit | 7a0ba875a7dcee94ec74fa79b7f8a247d200a76c (patch) | |
tree | 5546b60d81db578332e09a7274b8275db9f6254b /lib/CodeGen | |
parent | dcdecf4a777e503b24de6b15a054d580b585c06c (diff) |
Name mangling for class template specializations and template arguments.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71861 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 036389d4c0..6f4ec0bd57 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -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. |