aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/Mangle.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-09-17 00:43:46 +0000
committerAnders Carlsson <andersca@mac.com>2009-09-17 00:43:46 +0000
commit7696737d41321cf20aef1aab1454872f2ff7a1c8 (patch)
treece1bb05d644e629cef242d07f92451015a5e4514 /lib/CodeGen/Mangle.cpp
parentc8930d6b15287c03fc29563b329f1b6353092769 (diff)
Add basic substitution to the C++ mangler. It currently only looks at types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82102 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/Mangle.cpp')
-rw-r--r--lib/CodeGen/Mangle.cpp80
1 files changed, 72 insertions, 8 deletions
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index f55e99a573..3d7fc83322 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -35,6 +35,8 @@ namespace {
unsigned StructorType;
CXXCtorType CtorType;
+ llvm::DenseMap<uintptr_t, unsigned> Substitutions;
+
public:
CXXNameMangler(ASTContext &C, llvm::raw_ostream &os)
: Context(C), Out(os), Structor(0), StructorType(0) { }
@@ -53,6 +55,9 @@ namespace {
void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type);
private:
+ bool mangleSubstitution(QualType T);
+ void addSubstitution(QualType T);
+
bool mangleFunctionDecl(const FunctionDecl *FD);
void mangleFunctionEncoding(const FunctionDecl *FD);
@@ -521,20 +526,33 @@ void CXXNameMangler::mangleType(QualType T) {
// Only operate on the canonical type!
T = Context.getCanonicalType(T);
- // <type> ::= <CV-qualifiers> <type>
- mangleCVQualifiers(T.getCVRQualifiers());
+ bool IsSubstitutable = !isa<BuiltinType>(T);
+ if (IsSubstitutable && mangleSubstitution(T))
+ return;
+
+ if (unsigned CVRQualifiers = T.getCVRQualifiers()) {
+ // <type> ::= <CV-qualifiers> <type>
+ mangleCVQualifiers(CVRQualifiers);
- switch (T->getTypeClass()) {
+ mangleType(T.getUnqualifiedType());
+ } else {
+ switch (T->getTypeClass()) {
#define ABSTRACT_TYPE(CLASS, PARENT)
#define NON_CANONICAL_TYPE(CLASS, PARENT) \
- case Type::CLASS: \
- llvm::llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
- return;
+ case Type::CLASS: \
+ llvm::llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
+ return;
#define TYPE(CLASS, PARENT) \
- case Type::CLASS: \
- return mangleType(static_cast<CLASS##Type*>(T.getTypePtr()));
+ case Type::CLASS: \
+ mangleType(static_cast<CLASS##Type*>(T.getTypePtr())); \
+ break;
#include "clang/AST/TypeNodes.def"
+ }
}
+
+ // Add the substitution.
+ if (IsSubstitutable)
+ addSubstitution(T);
}
void CXXNameMangler::mangleType(const BuiltinType *T) {
@@ -868,6 +886,52 @@ void CXXNameMangler::mangleTemplateArgument(const TemplateArgument &A) {
}
}
+// <substitution> ::= S <seq-id> _
+// ::= S_
+bool CXXNameMangler::mangleSubstitution(QualType T) {
+ uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+
+ llvm::DenseMap<uintptr_t, unsigned>::iterator I =
+ Substitutions.find(TypePtr);
+ if (I == Substitutions.end())
+ return false;
+
+ unsigned SeqID = I->second;
+ if (SeqID == 0)
+ Out << "S_";
+ else {
+ SeqID--;
+
+ // <seq-id> is encoded in base-36, using digits and upper case letters.
+ char Buffer[10];
+ char *BufferPtr = Buffer + 9;
+
+ *BufferPtr = 0;
+ if (SeqID == 0) *--BufferPtr = '0';
+
+ while (SeqID) {
+ assert(BufferPtr > Buffer && "Buffer overflow!");
+
+ unsigned char c = static_cast<unsigned char>(SeqID) % 36;
+
+ *--BufferPtr = (c < 10 ? '0' + c : 'A' + c - 10);
+ SeqID /= 36;
+ }
+
+ Out << 'S' << BufferPtr << '_';
+ }
+
+ return true;
+}
+
+void CXXNameMangler::addSubstitution(QualType T) {
+ uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+ unsigned SeqID = Substitutions.size();
+
+ assert(!Substitutions.count(TypePtr) && "Substitution already exists!");
+ Substitutions[TypePtr] = SeqID;
+}
+
namespace clang {
/// \brief Mangles the name of the declaration D and emits that name to the
/// given output stream.