erichkeane created this revision.
erichkeane added reviewers: zturner, majnemer, compnerd, rnk.
Herald added subscribers: erik.pilkington, Anastasia.

All of the symbols demangle on llvm-undname and demangler.com.  This
address space qualifier is useful for when we want to use opencl C++ in
Windows mode.  Additionally, C++ address-space using functions will now
be usable on windows.


https://reviews.llvm.org/D55715

Files:
  lib/AST/MicrosoftMangle.cpp
  test/CodeGenCXX/mangle-address-space.cpp
  test/CodeGenOpenCL/address-spaces-mangling.cl

Index: test/CodeGenOpenCL/address-spaces-mangling.cl
===================================================================
--- test/CodeGenOpenCL/address-spaces-mangling.cl
+++ test/CodeGenOpenCL/address-spaces-mangling.cl
@@ -3,6 +3,11 @@
 // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=NOASMANG,NOASMAN10 %s
 // RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=NOASMANG,NOASMAN20 %s
 
+// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple x86_64-windows-pc -emit-llvm -o - | FileCheck -check-prefixes=MS_ASMANG,MS_ASMAN10 %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=yes -triple x86_64-windows-pc -emit-llvm -o - | FileCheck -check-prefixes=MS_ASMANG,MS_ASMAN20 %s
+// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple x86_64-windows-pc -emit-llvm -o - | FileCheck -check-prefixes=MS_NOASMANG,MS_NOASMAN10 %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=no -triple x86_64-windows-pc -emit-llvm -o - | FileCheck -check-prefixes=MS_NOASMANG,MS_NOASMAN20 %s
+
 // We check that the address spaces are mangled the same in both version of OpenCL
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -emit-llvm -o - | FileCheck -check-prefix=OCL-12 %s
@@ -16,6 +21,10 @@
 // ASMANG20: @_Z2ffPU3AS4i
 // NOASMANG10: @_Z2ffPi
 // NOASMANG20: @_Z2ffPU9CLgenerici
+// MS_ASMANG10: @_Z2ffPi
+// MS_ASMANG20: @_Z2ffPU3AS4i
+// MS_NOASMANG10: @_Z2ffPi
+// MS_NOASMANG20: @_Z2ffPU9CLgenerici
 // OCL-20-DAG: @_Z2ffPU3AS4i
 // OCL-12-DAG: @_Z2ffPi
 
@@ -23,6 +32,8 @@
 void f(private int *arg) { }
 // ASMANG: @_Z1fPi
 // NOASMANG: @_Z1fPU9CLprivatei
+// MS_ASMANG: @_Z1fPi
+// MS_NOASMANG: @_Z1fPU9CLprivatei
 // OCL-20-DAG: @_Z1fPi
 // OCL-12-DAG: @_Z1fPi
 
@@ -30,6 +41,8 @@
 void f(global int *arg) { }
 // ASMANG: @_Z1fPU3AS1i
 // NOASMANG: @_Z1fPU8CLglobali
+// MS_ASMANG: @_Z1fPU3AS1i
+// MS_NOASMANG: @_Z1fPU8CLglobali
 // OCL-20-DAG: @_Z1fPU3AS1i
 // OCL-12-DAG: @_Z1fPU3AS1i
 
@@ -37,6 +50,8 @@
 void f(local int *arg) { }
 // ASMANG: @_Z1fPU3AS3i
 // NOASMANG: @_Z1fPU7CLlocali
+// MS_ASMANG: @_Z1fPU3AS3i
+// MS_NOASMANG: @_Z1fPU7CLlocali
 // OCL-20-DAG: @_Z1fPU3AS3i
 // OCL-12-DAG: @_Z1fPU3AS3i
 
@@ -44,6 +59,8 @@
 void f(constant int *arg) { }
 // ASMANG: @_Z1fPU3AS2i
 // NOASMANG: @_Z1fPU10CLconstanti
+// MS_ASMANG: @_Z1fPU3AS2i
+// MS_NOASMANG: @_Z1fPU10CLconstanti
 // OCL-20-DAG: @_Z1fPU3AS2i
 // OCL-12-DAG: @_Z1fPU3AS2i
 
@@ -52,5 +69,7 @@
 void f(generic int *arg) { }
 // ASMANG20: @_Z1fPU3AS4i
 // NOASMANG20: @_Z1fPU9CLgenerici
+// MS_ASMANG20: @_Z1fPU3AS4i
+// MS_NOASMANG20: @_Z1fPU9CLgenerici
 // OCL-20-DAG: @_Z1fPU3AS4i
 #endif
Index: test/CodeGenCXX/mangle-address-space.cpp
===================================================================
--- test/CodeGenCXX/mangle-address-space.cpp
+++ test/CodeGenCXX/mangle-address-space.cpp
@@ -1,15 +1,64 @@
-// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s --check-prefixes=CHECK,CHECKNOOCL
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-windows-pc -o - %s | FileCheck %s --check-prefixes=WIN,WINNOOCL
+// RUN: %clang_cc1 -cl-std=c++ -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s --check-prefixes=CHECK,CHECKOCL
+// RUN: %clang_cc1 -cl-std=c++ -emit-llvm -triple x86_64-windows-pc -o - %s | FileCheck %s --check-prefixes=WIN,WINOCL
 
-// CHECK-LABEL: define {{.*}}void @_Z2f0Pc
+// CHECKNOOCL-LABEL: define {{.*}}void @_Z2f0Pc
+// WINNOOCL-LABEL: define {{.*}}void @"?f0@@YAXPEAD@Z"
+// CHECKOCL-LABEL: define {{.*}}void @_Z2f0PU9CLgenericc
+// WINOCL-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$AS_CLgeneric@$$CAD@__clang@@@Z" 
 void f0(char *p) { }
 // CHECK-LABEL: define {{.*}}void @_Z2f0PU3AS1c
+// WIN-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$AS_@$00$$CAD@__clang@@@Z"
 void f0(char __attribute__((address_space(1))) *p) { }
 
 struct OpaqueType;
 typedef OpaqueType __attribute__((address_space(100))) * OpaqueTypePtr;
 
 // CHECK-LABEL: define {{.*}}void @_Z2f0PU5AS10010OpaqueType
+// WIN-LABEL: define {{.*}}void @"?f0@@YAXPEAU?$AS_@$0GE@$$CAUOpaqueType@@@__clang@@@Z"
 void f0(OpaqueTypePtr) { }
 
 // CHECK-LABEL: define {{.*}}void @_Z2f1PU3AS1Kc
-void f1(char __attribute__((address_space(1))) const *p) {}
\ No newline at end of file
+// WIN-LABEL: define {{.*}}void @"?f1@@YAXPEAU?$AS_@$00$$CBD@__clang@@@Z"
+void f1(char __attribute__((address_space(1))) const *p) {}
+
+// Ensure we can do return values, which change in MS mode.
+// CHECK-LABEL: define {{.*}}float addrspace(1)* @_Z2f1PU3AS2Kc
+// WIN-LABEL: define {{.*}}float addrspace(1)* @"?f1@@YAPEAU?$AS_@$00$$CAM@__clang@@PEAU?$AS_@$01$$CBD@2@@Z"
+__attribute__((address_space(1))) float *f1(char __attribute__((address_space(2))) const *p) { return 0;}
+
+#if !defined(__OPENCL_CPP_VERSION__)
+// Return value of address space without a pointer is invalid in opencl.
+// Ensure we skip return values, since non-pointers aren't supposed to have an AS.
+// CHECKNOOCL-LABEL: define {{.*}}float @_Z2f2PU3AS2Kc
+// WINNOOCL-LABEL: define {{.*}}float @"?f2@@YA?AMQEAU?$AS_@$01$$CBD@__clang@@@Z"
+__attribute__((address_space(1))) float f2(char __attribute__((address_space(2))) const * const p) { return 0;}
+#endif
+
+#ifdef __OPENCL_CPP_VERSION__
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f0PU9CLprivatec
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f0@@YAXPEAU?$AS_CLprivate@$$CAD@__clang@@@Z"
+void ocl_f0(char __private *p) { }
+
+struct ocl_OpaqueType;
+typedef ocl_OpaqueType __global * ocl_OpaqueTypePtr;
+
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f0PU8CLglobal14ocl_OpaqueType
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f0@@YAXPEAU?$AS_CLglobal@$$CAUocl_OpaqueType@@@__clang@@@Z"
+void ocl_f0(ocl_OpaqueTypePtr) { }
+
+// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f1PU10CLconstantKc
+// WINOCL-LABEL: define {{.*}}void @"?ocl_f1@@YAXPEAU?$AS_CLconstant@$$CBD@__clang@@@Z"
+void ocl_f1(char __constant const *p) {}
+
+// Ensure we can do return values, which change in MS mode.
+// CHECKOCL-LABEL: define {{.*}}float* @_Z6ocl_f1PU9CLgenericKc
+// WINOCL-LABEL: define {{.*}}float* @"?ocl_f1@@YAPEAU?$AS_CLconstant@$$CAM@__clang@@PEAU?$AS_CLgeneric@$$CBD@2@@Z"
+__constant float *ocl_f1(char __generic const *p) { return 0;}
+
+// Ensure we skip return values, since non-pointers aren't supposed to have an AS.
+// CHECKOCL-LABEL: define {{.*}}float* @_Z6ocl_f2PU9CLgenericKc
+// WINOCL-LABEL: define {{.*}}float* @"?ocl_f2@@YAPEAU?$AS_CLgeneric@$$CAM@__clang@@QEAU?$AS_CLgeneric@$$CBD@2@@Z"
+__generic float *ocl_f2(__generic char const * const p) { return 0;}
+#endif
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -311,6 +311,7 @@
   void mangleTagTypeKind(TagTypeKind TK);
   void mangleArtificialTagType(TagTypeKind TK, StringRef UnqualifiedName,
                               ArrayRef<StringRef> NestedNames = None);
+  void mangleAddressSpaceType(QualType T, Qualifiers Quals, SourceRange Range);
   void mangleType(QualType T, SourceRange Range,
                   QualifierMangleMode QMM = QMM_Mangle);
   void mangleFunctionType(const FunctionType *T,
@@ -1777,12 +1778,77 @@
   }
 }
 
+void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
+                                                     Qualifiers Quals,
+                                                     SourceRange Range) {
+  // Address space is mangled as an unqualified templated type in the __clang
+  // namespace. The demangled version of this is:
+  // In the case of a language specific address space:
+  // __clang::struct AS_[language_addr_space]<Type>
+  // where:
+  //  <language_addr_space> ::= <OpenCL-addrspace> | <CUDA-addrspace>
+  //    <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |
+  //                                "private"| "generic" ]
+  //    <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
+  //    Note that the above were chosen to match the Itanium mangling for this.
+  //
+  // In the case of a non-language specific address space:
+  //  __clang::struct AS_<TargetAS, Type>
+  assert(Quals.hasAddressSpace() && "Not valid without address space");
+  llvm::SmallString<32> ASMangling;
+  llvm::raw_svector_ostream Stream(ASMangling);
+  MicrosoftCXXNameMangler Extra(Context, Stream);
+  Stream << "?$";
+
+  LangAS AS = Quals.getAddressSpace();
+  if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
+    unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
+    Extra.mangleSourceName("AS_");
+    Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS),
+                               /*IsBoolean*/ false);
+  } else {
+    switch (AS) {
+    default:
+      llvm_unreachable("Not a language specific address space");
+    case LangAS::opencl_global:
+      Extra.mangleSourceName("AS_CLglobal");
+      break;
+    case LangAS::opencl_local:
+      Extra.mangleSourceName("AS_CLlocal");
+      break;
+    case LangAS::opencl_constant:
+      Extra.mangleSourceName("AS_CLconstant");
+      break;
+    case LangAS::opencl_private:
+      Extra.mangleSourceName("AS_CLprivate");
+      break;
+    case LangAS::opencl_generic:
+      Extra.mangleSourceName("AS_CLgeneric");
+      break;
+    case LangAS::cuda_device:
+      Extra.mangleSourceName("AS_CUdevice");
+      break;
+    case LangAS::cuda_constant:
+      Extra.mangleSourceName("AS_CUconstant");
+      break;
+    case LangAS::cuda_shared:
+      Extra.mangleSourceName("AS_CUshared");
+      break;
+    }
+  }
+
+  Extra.mangleType(T, Range, QMM_Escape);
+  mangleQualifiers(Qualifiers(), false);
+  mangleArtificialTagType(TTK_Struct, ASMangling, {"__clang"});
+}
+
 void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
                                          QualifierMangleMode QMM) {
   // Don't use the canonical types.  MSVC includes things like 'const' on
   // pointer arguments to function pointers that canonicalization strips away.
   T = T.getDesugaredType(getASTContext());
   Qualifiers Quals = T.getLocalQualifiers();
+
   if (const ArrayType *AT = getASTContext().getAsArrayType(T)) {
     // If there were any Quals, getAsArrayType() pushed them onto the array
     // element type.
@@ -2488,7 +2554,11 @@
   QualType PointeeType = T->getPointeeType();
   manglePointerCVQualifiers(Quals);
   manglePointerExtQualifiers(Quals, PointeeType);
-  mangleType(PointeeType, Range);
+
+  if (PointeeType.getQualifiers().hasAddressSpace())
+    mangleAddressSpaceType(PointeeType, PointeeType.getQualifiers(), Range);
+  else
+    mangleType(PointeeType, Range);
 }
 
 void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to