[cfe-commits] r107264 - in /cfe/trunk: lib/CodeGen/MicrosoftCXXABI.cpp test/CodeGenCXX/mangle-ms.cpp
Charles Davis
cdavis at mines.edu
Wed Jun 30 01:09:57 PDT 2010
Author: cdavis
Date: Wed Jun 30 03:09:57 2010
New Revision: 107264
URL: http://llvm.org/viewvc/llvm-project?rev=107264&view=rev
Log:
Mangle arrays in the Microsoft C++ Mangler. It's not quite finished (it
doesn't mangle array parameters right), but I think that should be fixed
in Sema (Doug, John, what do you think?).
Also, stub out the remaining mangleType() routines.
Modified:
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=107264&r1=107263&r2=107264&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Jun 30 03:09:57 2010
@@ -70,6 +70,8 @@
void mangleType(const TagType*);
void mangleType(const FunctionType *T, bool IsStructor, bool IsInstMethod);
+ void mangleType(const ArrayType *T, bool IsGlobal);
+ void mangleExtraDimensions(QualType T);
void mangleFunctionClass(const FunctionDecl *FD);
void mangleCallingConvention(const FunctionType *T);
void mangleThrowSpecification(const FunctionProtoType *T);
@@ -243,13 +245,17 @@
Out << '4';
// Now mangle the type.
// <variable-type> ::= <type> <cvr-qualifiers>
- // ::= <type> A # pointers and references
+ // ::= <type> A # pointers, references, arrays
// Pointers and references are odd. The type of 'int * const foo;' gets
// mangled as 'QAHA' instead of 'PAHB', for example.
QualType Ty = VD->getType();
if (Ty->isPointerType() || Ty->isReferenceType()) {
mangleType(Ty);
Out << 'A';
+ } else if (Ty->isArrayType()) {
+ // Global arrays are funny, too.
+ mangleType(static_cast<ArrayType *>(Ty.getTypePtr()), true);
+ Out << 'A';
} else {
mangleType(Ty.getLocalUnqualifiedType());
mangleQualifiers(Ty.getLocalQualifiers(), false);
@@ -662,26 +668,11 @@
case Type::CLASS: \
llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
return;
-#define TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) \
+case Type::CLASS: \
+mangleType(static_cast<const CLASS##Type*>(T.getTypePtr())); \
+break;
#include "clang/AST/TypeNodes.def"
- case Type::Builtin:
- mangleType(static_cast<BuiltinType *>(T.getTypePtr()));
- break;
- case Type::Enum:
- mangleType(static_cast<EnumType *>(T.getTypePtr()));
- break;
- case Type::Record:
- mangleType(static_cast<RecordType *>(T.getTypePtr()));
- break;
- case Type::Pointer:
- mangleType(static_cast<PointerType *>(T.getTypePtr()));
- break;
- case Type::LValueReference:
- mangleType(static_cast<LValueReferenceType *>(T.getTypePtr()));
- break;
- default:
- assert(false && "Don't know how to mangle this type!");
- break;
}
}
@@ -763,7 +754,8 @@
void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T) {
// Structors only appear in decls, so at this point we know it's not a
// structor type.
- // I'll probably have mangleType(MemberPointerType) call
+ // I'll probably have mangleType(MemberPointerType) call the mangleType()
+ // method directly.
mangleType(T, false, false);
}
void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T) {
@@ -801,7 +793,7 @@
ArgEnd = Proto->arg_type_end();
Arg != ArgEnd; ++Arg)
mangleType(*Arg);
-
+
// <builtin-type> ::= Z # ellipsis
if (Proto->isVariadic())
Out << 'Z';
@@ -904,6 +896,10 @@
Out << 'Z';
}
+void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T) {
+ assert(false && "Don't know how to mangle UnresolvedUsingTypes yet!");
+}
+
// <type> ::= <union-type> | <struct-type> | <class-type> | <enum-type>
// <union-type> ::= T <name>
// <struct-type> ::= U <name>
@@ -935,14 +931,88 @@
mangleName(T->getDecl());
}
+// <type> ::= <array-type>
+// <array-type> ::= P <cvr-qualifiers> [Y <dimension-count> <dimension>+]
+// <element-type> # as global
+// ::= Q <cvr-qualifiers> [Y <dimension-count> <dimension>+]
+// <element-type> # as param
+// It's supposed to be the other way around, but for some strange reason, it
+// isn't. Today this behavior is retained for the sole purpose of backwards
+// compatibility.
+void MicrosoftCXXNameMangler::mangleType(const ArrayType *T, bool IsGlobal) {
+ // This isn't a recursive mangling, so now we have to do it all in this
+ // one call.
+ if (IsGlobal)
+ Out << 'P';
+ else
+ Out << 'Q';
+ mangleExtraDimensions(T->getElementType());
+}
+void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T) {
+ mangleType(static_cast<const ArrayType *>(T), false);
+}
+void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T) {
+ mangleType(static_cast<const ArrayType *>(T), false);
+}
+void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T) {
+ mangleType(static_cast<const ArrayType *>(T), false);
+}
+void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T) {
+ mangleType(static_cast<const ArrayType *>(T), false);
+}
+void MicrosoftCXXNameMangler::mangleExtraDimensions(QualType ElementTy) {
+ llvm::SmallVector<llvm::APInt, 3> Dimensions;
+ for (;;) {
+ if (ElementTy->isConstantArrayType()) {
+ const ConstantArrayType *CAT =
+ static_cast<const ConstantArrayType *>(ElementTy.getTypePtr());
+ Dimensions.push_back(CAT->getSize()-1);
+ ElementTy = CAT->getElementType();
+ } else if (ElementTy->isVariableArrayType()) {
+ assert(false && "Don't know how to mangle VLAs!");
+ } else if (ElementTy->isDependentSizedArrayType()) {
+ // The dependent expression has to be folded into a constant (TODO).
+ assert(false && "Don't know how to mangle dependent-sized arrays!");
+ } else if (ElementTy->isIncompleteArrayType()) continue;
+ else break;
+ }
+ mangleQualifiers(ElementTy.getQualifiers(), false);
+ // If there are any additional dimensions, mangle them now.
+ if (Dimensions.size() > 0) {
+ Out << 'Y';
+ // <dimension-count> ::= <number> # number of extra dimensions minus 1
+ mangleNumber(Dimensions.size()-1);
+ for (unsigned Dim = 0; Dim < Dimensions.size(); ++Dim) {
+ mangleNumber(Dimensions[Dim].getLimitedValue());
+ }
+ }
+ mangleType(ElementTy.getLocalUnqualifiedType());
+}
+
+void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T) {
+ assert(false && "Don't know how to mangle MemberPointerTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T) {
+ assert(false && "Don't know how to mangle TemplateTypeParmTypes yet!");
+}
+
// <type> ::= <pointer-type>
// <pointer-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
void MicrosoftCXXNameMangler::mangleType(const PointerType *T) {
QualType PointeeTy = T->getPointeeType();
- if (!PointeeTy.hasLocalQualifiers())
- // Lack of qualifiers is mangled as 'A'.
- Out << 'A';
- mangleType(PointeeTy);
+ if (PointeeTy->isArrayType()) {
+ // Pointers to arrays are mangled like arrays.
+ mangleExtraDimensions(T->getPointeeType());
+ } else {
+ if (!PointeeTy.hasQualifiers())
+ // Lack of qualifiers is mangled as 'A'.
+ Out << 'A';
+ mangleType(PointeeTy);
+ }
+}
+void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T) {
+ assert(false && "Don't know how to mangle ObjCObjectPointerTypes yet!");
}
// <type> ::= <reference-type>
@@ -950,12 +1020,72 @@
void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T) {
Out << 'A';
QualType PointeeTy = T->getPointeeType();
- if (!PointeeTy.hasLocalQualifiers())
+ if (!PointeeTy.hasQualifiers())
// Lack of qualifiers is mangled as 'A'.
Out << 'A';
mangleType(PointeeTy);
}
+void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T) {
+ assert(false && "Don't know how to mangle RValueReferenceTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const ComplexType *T) {
+ assert(false && "Don't know how to mangle ComplexTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const VectorType *T) {
+ assert(false && "Don't know how to mangle VectorTypes yet!");
+}
+void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T) {
+ assert(false && "Don't know how to mangle ExtVectorTypes yet!");
+}
+void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T) {
+ assert(false && "Don't know how to mangle DependentSizedExtVectorTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T) {
+ assert(false && "Don't know how to mangle ObjCInterfaceTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T) {
+ assert(false && "Don't know how to mangle ObjCObjectTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T) {
+ assert(false && "Don't know how to mangle BlockPointerTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *T) {
+ assert(false && "Don't know how to mangle InjectedClassNameTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T) {
+ assert(false && "Don't know how to mangle TemplateSpecializationTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T) {
+ assert(false && "Don't know how to mangle DependentNameTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(
+ const DependentTemplateSpecializationType *T) {
+ assert(false &&
+ "Don't know how to mangle DependentTemplateSpecializationTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T) {
+ assert(false && "Don't know how to mangle TypeOfTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T) {
+ assert(false && "Don't know how to mangle TypeOfExprTypes yet!");
+}
+
+void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T) {
+ assert(false && "Don't know how to mangle DecltypeTypes yet!");
+}
+
void MicrosoftMangleContext::mangleName(const NamedDecl *D,
llvm::SmallVectorImpl<char> &Name) {
assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
Modified: cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms.cpp?rev=107264&r1=107263&r2=107264&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms.cpp Wed Jun 30 03:09:57 2010
@@ -8,6 +8,7 @@
// CHECK: @"\01?f at foo@@2DD"
// CHECK: @"\01?g at bar@@2HA"
// CHECK: @"\01?h@@3QAHA"
+// CHECK: @"\01?i@@3PAY0BD at HA"
int a;
@@ -42,6 +43,8 @@
qthree
};
+// NOTE: The calling convention is supposed to be __thiscall by default,
+// but that needs to be fixed in Sema/AST.
int foo::operator+(int a) {return a;}
// CHECK: @"\01??Hfoo@@QAAHH at Z"
@@ -53,6 +56,8 @@
extern int * const h = &a;
+int i[10][20];
+
// Static functions are mangled, too.
// Also make sure calling conventions, arglists, and throw specs work.
static void __stdcall alpha(float a, double b) throw() {}
@@ -71,3 +76,8 @@
// Make sure pointer/reference-type mangling works.
void delta(int * const a, const long &) {}
// CHECK: @"\01?delta@@YAXQAHABJ at Z"
+
+// Array mangling. (It should be mangled as a const pointer, but that needs
+// to be fixed in Sema.)
+void epsilon(int a[][10][20]) {}
+// CHECK: @"\01?epsilon@@YAXPAY19BD at H@Z"
More information about the cfe-commits
mailing list