[PATCH] [-cxx-abi microsoft] Canonicalize array parameters better
David Majnemer
david.majnemer at gmail.com
Tue Sep 10 21:46:10 PDT 2013
- Some fixes.
- No need to go through AST.
Hi rnk, timurrrr, whunt, cdavis5x,
http://llvm-reviews.chandlerc.com/D1626
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1626?vs=4185&id=4186#toc
Files:
lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -125,7 +125,7 @@
#undef TYPE
void mangleType(const TagDecl *TD);
- void mangleDecayedArrayType(const ArrayType *T, bool IsGlobal);
+ void mangleDecayedArrayType(const ArrayType *T);
void mangleArrayType(const ArrayType *T);
void mangleFunctionClass(const FunctionDecl *FD);
void mangleCallingConvention(const FunctionType *T, bool IsInstMethod = false);
@@ -337,7 +337,7 @@
mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
} else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
// Global arrays are funny, too.
- mangleDecayedArrayType(AT, true);
+ mangleDecayedArrayType(AT);
if (AT->getElementType()->isArrayType())
Out << 'A';
else
@@ -1057,25 +1057,30 @@
SourceRange Range) {
// MSVC will backreference two canonically equivalent types that have slightly
// different manglings when mangled alone.
- void *TypePtr = getASTContext().getCanonicalType(T).getAsOpaquePtr();
+
+ // Decayed types do not match up with non-decayed versions of the same type.
+ //
+ // e.g.
+ // void (*x)(void) will not form a backreference with void x(void)
+ void *TypePtr;
+ if (const DecayedType *DT = T->getAs<DecayedType>()) {
+ TypePtr = DT->getOriginalType().getCanonicalType().getAsOpaquePtr();
+ // If the original parameter was textually written as an array,
+ // instead treat the decayed parameter like it's const.
+ //
+ // e.g.
+ // int [] -> int * const
+ if (DT->getOriginalType()->isArrayType())
+ T = T.withConst();
+ } else
+ TypePtr = T.getCanonicalType().getAsOpaquePtr();
+
ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr);
if (Found == TypeBackReferences.end()) {
size_t OutSizeBefore = Out.GetNumBytesInBuffer();
- if (const DecayedType *DT = T->getAs<DecayedType>()) {
- QualType OT = DT->getOriginalType();
- if (const ArrayType *AT = getASTContext().getAsArrayType(OT)) {
- mangleDecayedArrayType(AT, false);
- } else if (const FunctionType *FT = OT->getAs<FunctionType>()) {
- Out << "P6";
- mangleFunctionType(FT, 0, false, false);
- } else {
- llvm_unreachable("unexpected decayed type");
- }
- } else {
- mangleType(T, Range, QMM_Drop);
- }
+ mangleType(T, Range, QMM_Drop);
// See if it's worth creating a back reference.
// Only types longer than 1 character are considered
@@ -1467,22 +1472,13 @@
// <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
// [Y <dimension-count> <dimension>+]
// <element-type> # as global, E is never required
-// ::= Q E? <cvr-qualifiers> [Y <dimension-count> <dimension>+]
-// <element-type> # as param, E is required for 64-bit
// 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::mangleDecayedArrayType(const ArrayType *T,
- bool IsGlobal) {
+void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {
// This isn't a recursive mangling, so now we have to do it all in this
// one call.
- if (IsGlobal) {
- manglePointerQualifiers(T->getElementType().getQualifiers());
- } else {
- Out << 'Q';
- if (PointersAre64Bit)
- Out << 'E';
- }
+ manglePointerQualifiers(T->getElementType().getQualifiers());
mangleType(T->getElementType(), SourceRange());
}
void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T,
Index: test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
===================================================================
--- test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
+++ test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
@@ -204,3 +204,37 @@
void mangle_no_fwd(char * x) {}
// CHECK: "\01?mangle_no_fwd@@YAXPAD at Z"
// X64: "\01?mangle_no_fwd@@YAXPEAD at Z"
+
+// The first argument gets mangled as-if it were written "int *const"
+// The second arg should not form a backref because it isn't qualified
+void mangle_no_backref0(int[], int *) {}
+// CHECK: "\01?mangle_no_backref0@@YAXQAHPAH at Z"
+// X64: "\01?mangle_no_backref0@@YAXQEAHPEAH at Z"
+
+void mangle_no_backref1(int[], int *const) {}
+// CHECK: "\01?mangle_no_backref1@@YAXQAHQAH at Z"
+// X64: "\01?mangle_no_backref1@@YAXQEAHQEAH at Z"
+
+typedef void fun_type(void);
+typedef void (*ptr_to_fun_type)(void);
+
+// Pointer to function types don't backref with function types
+void mangle_no_backref2(fun_type, ptr_to_fun_type) {}
+// CHECK: "\01?mangle_no_backref2@@YAXP6AXXZP6AXXZ at Z"
+// X64: "\01?mangle_no_backref2@@YAXP6AXXZP6AXXZ at Z"
+
+void mangle_yes_backref0(int[], int []) {}
+// CHECK: "\01?mangle_yes_backref0@@YAXQAH0 at Z"
+// X64: "\01?mangle_yes_backref0@@YAXQEAH0 at Z"
+
+void mangle_yes_backref1(int *const, int *const) {}
+// CHECK: "\01?mangle_yes_backref1@@YAXQAH0 at Z"
+// X64: "\01?mangle_yes_backref1@@YAXQEAH0 at Z"
+
+void mangle_yes_backref2(fun_type *const[], ptr_to_fun_type const[]) {}
+// CHECK: "\01?mangle_yes_backref2@@YAXQBQ6AXXZ0 at Z"
+// X64: "\01?mangle_yes_backref2@@YAXQEBQ6AXXZ0 at Z"
+
+void mangle_yes_backref3(ptr_to_fun_type *const, void (**const)(void)) {}
+// CHECK: "\01?mangle_yes_backref3@@YAXQAP6AXXZ0 at Z"
+// X64: "\01?mangle_yes_backref3@@YAXQEAP6AXXZ0 at Z"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1626.3.patch
Type: text/x-patch
Size: 5610 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130910/14d8c49f/attachment.bin>
More information about the cfe-commits
mailing list