smeenai updated this revision to Diff 173965.
smeenai added a comment.

Stateful approach


Repository:
  rC Clang

https://reviews.llvm.org/D52674

Files:
  lib/AST/MicrosoftMangle.cpp
  test/CodeGenObjCXX/msabi-objc-exceptions-gnustep.mm

Index: test/CodeGenObjCXX/msabi-objc-exceptions-gnustep.mm
===================================================================
--- /dev/null
+++ test/CodeGenObjCXX/msabi-objc-exceptions-gnustep.mm
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fobjc-runtime=gnustep-2.0 -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefix=X86 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fobjc-runtime=gnustep-2.0 -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefix=X64 %s
+
+// Ensure we have the __ObjC::class discriminator in the RTTI and the RTTI name.
+// X86-DAG: @"??_R0PAU?$Class@Uobjc_object@@@__ObjC@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [36 x i8] c".PAU?$Class@Uobjc_object@@@__ObjC@@\00" }, comdat
+// X64-DAG: @"??_R0PEAU?$Class@Uobjc_object@@@__ObjC@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [37 x i8] c".PEAU?$Class@Uobjc_object@@@__ObjC@@\00" }, comdat
+
+@class I;
+// X86-DAG: @"??_R0PAU?$Class@UI@@@__ObjC@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [26 x i8] c".PAU?$Class@UI@@@__ObjC@@\00" }, comdat
+// X64-DAG: @"??_R0PEAU?$Class@UI@@@__ObjC@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [27 x i8] c".PEAU?$Class@UI@@@__ObjC@@\00" }, comdat
+
+void f();
+void g() {
+  @try {
+    f();
+  } @catch (I *) {
+  } @catch (id) {
+  }
+}
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -252,6 +252,11 @@
 /// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
 /// Microsoft Visual C++ ABI.
 class MicrosoftCXXNameMangler {
+public:
+  enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
+  enum ForRTTI_t : bool { NotForRTTI = false, ForRTTI = true };
+
+private:
   MicrosoftMangleContextImpl &Context;
   raw_ostream &Out;
 
@@ -276,25 +281,35 @@
   // this check into mangleQualifiers().
   const bool PointersAre64Bit;
 
-public:
-  enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
+  ForRTTI_t IsForRTTI;
 
+public:
   MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
       : Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
         PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
-                         64) {}
+                         64),
+        IsForRTTI(NotForRTTI) {}
 
   MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
                           const CXXConstructorDecl *D, CXXCtorType Type)
       : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
         PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
-                         64) {}
+                         64),
+        IsForRTTI(NotForRTTI) {}
 
   MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
                           const CXXDestructorDecl *D, CXXDtorType Type)
       : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
         PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
-                         64) {}
+                         64),
+        IsForRTTI(NotForRTTI) {}
+
+  MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
+                          ForRTTI_t IsForRTTI)
+      : Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
+        PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
+                         64),
+        IsForRTTI(IsForRTTI) {}
 
   raw_ostream &getStream() const { return Out; }
 
@@ -339,6 +354,7 @@
   void
   mangleTemplateInstantiationName(const TemplateDecl *TD,
                                   const TemplateArgumentList &TemplateArgs);
+  void mangleObjCClassName(StringRef Name);
   void mangleObjCMethodName(const ObjCMethodDecl *MD);
 
   void mangleArgumentType(QualType T, SourceRange Range);
@@ -1277,6 +1293,27 @@
   }
 }
 
+void MicrosoftCXXNameMangler::mangleObjCClassName(StringRef Name) {
+  // Obj-C classes are normally mangled as C++ structs with the same name, but
+  // we want to be able to distinguish a C++ struct X from an Obj-C class X for
+  // the purposes of exception handling, so we add a discriminator when mangling
+  // for RTTI.
+  if (!IsForRTTI) {
+    mangleArtificalTagType(TTK_Struct, Name);
+    return;
+  }
+
+  llvm::SmallString<64> TemplateMangling;
+  llvm::raw_svector_ostream Stream(TemplateMangling);
+  MicrosoftCXXNameMangler Extra(Context, Stream);
+
+  Stream << "?$";
+  Extra.mangleSourceName("Class");
+  Extra.mangleArtificalTagType(TTK_Struct, Name);
+
+  mangleArtificalTagType(TTK_Struct, TemplateMangling, {"__ObjC"});
+}
+
 void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
   Context.mangleObjCMethodName(MD, Out);
 }
@@ -1951,7 +1988,7 @@
     llvm_unreachable("placeholder types shouldn't get to name mangling");
 
   case BuiltinType::ObjCId:
-    mangleArtificalTagType(TTK_Struct, "objc_object");
+    mangleObjCClassName("objc_object");
     break;
   case BuiltinType::ObjCClass:
     mangleArtificalTagType(TTK_Struct, "objc_class");
@@ -2644,9 +2681,7 @@
 
 void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,
                                          SourceRange) {
-  // ObjC interfaces have structs underlying them.
-  mangleTagTypeKind(TTK_Struct);
-  mangleName(T->getDecl());
+  mangleObjCClassName(T->getDecl()->getName());
 }
 
 void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,
@@ -3006,15 +3041,15 @@
 
 void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
   msvc_hashing_ostream MHO(Out);
-  MicrosoftCXXNameMangler Mangler(*this, MHO);
+  MicrosoftCXXNameMangler Mangler(*this, MHO, MicrosoftCXXNameMangler::ForRTTI);
   Mangler.getStream() << "??_R0";
   Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
   Mangler.getStream() << "@8";
 }
 
 void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T,
                                                    raw_ostream &Out) {
-  MicrosoftCXXNameMangler Mangler(*this, Out);
+  MicrosoftCXXNameMangler Mangler(*this, Out, MicrosoftCXXNameMangler::ForRTTI);
   Mangler.getStream() << '.';
   Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to