forked from OSchip/llvm-project
Add AddressSpace mangling to MS mode
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. Differential Revision: https://reviews.llvm.org/D55715 Change-Id: Ife4506613c3cce778a783456d62117fbf7d83c26 llvm-svn: 349209
This commit is contained in:
parent
0127883373
commit
24a0f04f77
|
@ -311,6 +311,7 @@ public:
|
|||
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::manglePassObjectSizeArg(
|
|||
}
|
||||
}
|
||||
|
||||
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("_ASCLglobal");
|
||||
break;
|
||||
case LangAS::opencl_local:
|
||||
Extra.mangleSourceName("_ASCLlocal");
|
||||
break;
|
||||
case LangAS::opencl_constant:
|
||||
Extra.mangleSourceName("_ASCLconstant");
|
||||
break;
|
||||
case LangAS::opencl_private:
|
||||
Extra.mangleSourceName("_ASCLprivate");
|
||||
break;
|
||||
case LangAS::opencl_generic:
|
||||
Extra.mangleSourceName("_ASCLgeneric");
|
||||
break;
|
||||
case LangAS::cuda_device:
|
||||
Extra.mangleSourceName("_ASCUdevice");
|
||||
break;
|
||||
case LangAS::cuda_constant:
|
||||
Extra.mangleSourceName("_ASCUconstant");
|
||||
break;
|
||||
case LangAS::cuda_shared:
|
||||
Extra.mangleSourceName("_ASCUshared");
|
||||
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 @@ void MicrosoftCXXNameMangler::mangleType(const PointerType *T, Qualifiers Quals,
|
|||
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,
|
||||
|
|
|
@ -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-msvc -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-msvc -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?$_ASCLgeneric@$$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) {}
|
||||
// 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?$_ASCLprivate@$$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?$_ASCLglobal@$$CAUocl_OpaqueType@@@__clang@@@Z"
|
||||
void ocl_f0(ocl_OpaqueTypePtr) { }
|
||||
|
||||
// CHECKOCL-LABEL: define {{.*}}void @_Z6ocl_f1PU10CLconstantKc
|
||||
// WINOCL-LABEL: define {{.*}}void @"?ocl_f1@@YAXPEAU?$_ASCLconstant@$$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?$_ASCLconstant@$$CAM@__clang@@PEAU?$_ASCLgeneric@$$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?$_ASCLgeneric@$$CAM@__clang@@QEAU?$_ASCLgeneric@$$CBD@2@@Z"
|
||||
__generic float *ocl_f2(__generic char const * const p) { return 0;}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue