forked from OSchip/llvm-project
Add basic substitution to the C++ mangler. It currently only looks at types.
llvm-svn: 82102
This commit is contained in:
parent
db7ec04fed
commit
feb60501a8
|
@ -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;
|
||||
|
||||
switch (T->getTypeClass()) {
|
||||
if (unsigned CVRQualifiers = T.getCVRQualifiers()) {
|
||||
// <type> ::= <CV-qualifiers> <type>
|
||||
mangleCVQualifiers(CVRQualifiers);
|
||||
|
||||
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.
|
||||
|
|
|
@ -9,10 +9,10 @@ T* next(T* ptr, const U& diff) {
|
|||
|
||||
void test(int *iptr, float *fptr, int diff) {
|
||||
// FIXME: should be "_Z4nextIiiEPT_S1_RKT0_"
|
||||
// RUN: grep "_Z4nextIiiEPiPiRKi" %t &&
|
||||
// RUN: grep "_Z4nextIiiEPiS_RKi" %t &&
|
||||
iptr = next(iptr, diff);
|
||||
// FIXME: should be "_Z4nextIfiEPT_S1_RKT0_"
|
||||
// RUN: grep "_Z4nextIfiEPfPfRKi" %t &&
|
||||
// RUN: grep "_Z4nextIfiEPfS_RKi" %t &&
|
||||
fptr = next(fptr, diff);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,6 @@ T* next(T* ptr, const U& diff);
|
|||
void test2(int *iptr, double *dptr, int diff) {
|
||||
iptr = next(iptr, diff);
|
||||
// FIXME: should be "_Z4nextIdiEPT_S1_RKT0_"
|
||||
// RUN: grep "_Z4nextIdiEPdPdRKi" %t
|
||||
// RUN: grep "_Z4nextIdiEPdS_RKi" %t
|
||||
dptr = next(dptr, diff);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin10 &&
|
||||
|
||||
struct X { };
|
||||
|
||||
// RUN: grep "define void @_Z1fPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP1XS13_S12_S11_S10_SZ_SY_SX_SW_SV_SU_ST_SS_SR_SQ_SP_SO_SN_SM_SL_SK_SJ_SI_SH_SG_SF_SE_SD_SC_SB_SA_S9_S8_S7_S6_S5_S4_S3_S2_S1_S0_S_(" %t &&
|
||||
void f(X****************************************,
|
||||
X****************************************,
|
||||
X***************************************,
|
||||
X**************************************,
|
||||
X*************************************,
|
||||
X************************************,
|
||||
X***********************************,
|
||||
X**********************************,
|
||||
X*********************************,
|
||||
X********************************,
|
||||
X*******************************,
|
||||
X******************************,
|
||||
X*****************************,
|
||||
X****************************,
|
||||
X***************************,
|
||||
X**************************,
|
||||
X*************************,
|
||||
X************************,
|
||||
X***********************,
|
||||
X**********************,
|
||||
X*********************,
|
||||
X********************,
|
||||
X*******************,
|
||||
X******************,
|
||||
X*****************,
|
||||
X****************,
|
||||
X***************,
|
||||
X**************,
|
||||
X*************,
|
||||
X************,
|
||||
X***********,
|
||||
X**********,
|
||||
X*********,
|
||||
X********,
|
||||
X*******,
|
||||
X******,
|
||||
X*****,
|
||||
X****,
|
||||
X***,
|
||||
X**,
|
||||
X*,
|
||||
X) { }
|
||||
|
||||
// RUN: true
|
|
@ -0,0 +1,20 @@
|
|||
// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 &&
|
||||
|
||||
struct X {};
|
||||
|
||||
// RUN: grep "define void @_Z1f1XS_" %t | count 1 &&
|
||||
void f(X, X) { }
|
||||
|
||||
// RUN: grep "define void @_Z1fR1XS0_" %t | count 1 &&
|
||||
void f(X&, X&) { }
|
||||
|
||||
// RUN: grep "define void @_Z1fRK1XS1_" %t | count 1 &&
|
||||
void f(const X&, const X&) { }
|
||||
|
||||
typedef void T();
|
||||
struct S {};
|
||||
|
||||
// RUN: grep "define void @_Z1fPFvvEM1SFvvE" %t | count 1 &&
|
||||
void f(T*, T (S::*)) {}
|
||||
|
||||
// RUN: true
|
Loading…
Reference in New Issue