Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -9183,7 +9183,13 @@ class Sema final : public SemaBase {
};

/// Compute the mangling number context for a lambda expression or
/// block literal. Also return the extra mangling decl if any.
/// block literal that appears in the specified declaration context in
/// consideration of the current expression evaluation and template
/// instantiation contexts. If the mangling context requires external linkage,
/// then a mangling number context is returned in the first tuple
/// element. If the mangling context is non-normal (specialized for
/// lambda and block types relative to other entities), the overriding
/// declaration is returned in the second tuple element.
///
/// \param DC - The DeclContext containing the lambda expression or
/// block literal.
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13356,6 +13356,7 @@ MangleNumberingContext &
ASTContext::getManglingNumberContext(const DeclContext *DC) {
assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C.
std::unique_ptr<MangleNumberingContext> &MCtx = MangleNumberingContexts[DC];
DC = DC->getPrimaryContext();
if (!MCtx)
MCtx = createMangleNumberingContext();
return *MCtx;
Expand Down
9 changes: 8 additions & 1 deletion clang/lib/Sema/SemaLambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,14 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
return std::make_tuple(&Context.getManglingNumberContext(DC), nullptr);
}

return std::make_tuple(nullptr, nullptr);
if (ManglingContextDecl) {
// Lambdas defined in the initializer of a local variable are mangled
// in the enclosing function context.
if (auto *VD = dyn_cast<VarDecl>(ManglingContextDecl);
VD && !VD->hasGlobalStorage())
ManglingContextDecl = nullptr;
}
return std::make_tuple(nullptr, ManglingContextDecl);
}

case NonInlineInModulePurview:
Expand Down
61 changes: 61 additions & 0 deletions clang/test/CodeGen/unnamed-types.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// RUN: %clang_cc1 -O0 -triple x86_64-unknown-unknown \
// RUN: -emit-llvm %s -o - | FileCheck %s

// RUN: %clang_cc1 -O0 -triple x86_64-pc-windows-msvc \
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=MSVC

namespace QL {
auto dg1 = [] { return 1; };
inline auto dg_inline1 = [] { return 1; };
}

namespace QL {
auto dg2 = [] { return 2; };
template<int N>
auto dg_template = [] { return N; };
}

using namespace QL;
template<typename T>
void f(T t) {
t();
}

void g() {
f(dg1);
f(dg2);
f(dg_inline1);
f(dg_template<3>);
}

// CHECK: @_ZN2QL3dg1E = internal global %class.anon undef, align 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I understanding correctly that the variable names are now included in the mangling while it was not previously?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issues occur when using the -fsycl flag or internal OpenMP flags. Several problems can arise: depending on the scenario, either the lambda name mangling does not follow the Itanium ABI, or there are name collisions. For examples, see this https://godbolt.org/z/Yvvrjnnjv

// CHECK: @_ZN2QL3dg2E = internal global %class.anon.0 undef, align 1
// CHECK: @_ZN2QL10dg_inline1E = linkonce_odr global %class.anon.2 undef, comdat, align 1
// CHECK: @_ZN2QL11dg_templateILi3EEE = linkonce_odr global %class.anon.4 undef, comdat, align 1

// MSVC: @"?dg1@QL@@3V<lambda_0>@1@A" = internal global %class.anon undef, align 1
// MSVC: @"?dg2@QL@@3V<lambda_1>@1@A" = internal global %class.anon.0 undef, align 1
// MSVC: @"?dg_inline1@QL@@3V<lambda_1>@01@A" = linkonce_odr dso_local global %class.anon.2 undef, comdat, align 1
// MSVC: @"??$dg_template@$02@QL@@3V<lambda_1>@01@A" = linkonce_odr dso_local global %class.anon.4 undef, comdat, align 1


// CHECK: define internal void @"_Z1fIN2QL3$_0EEvT_"
// CHECK: call noundef i32 @"_ZNK2QL3$_0clEv"
// CHECK: define internal void @"_Z1fIN2QL3$_1EEvT_"
// CHECK: define linkonce_odr void @_Z1fIN2QL10dg_inline1MUlvE_EEvT_
// CHECK: call noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
// CHECK: define linkonce_odr void @_Z1fIN2QL11dg_templateILi3EEMUlvE_EEvT_
// CHECK: call noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv
// CHECK: define internal noundef i32 @"_ZNK2QL3$_0clEv"
// CHECK: define internal noundef i32 @"_ZNK2QL3$_1clEv"
// CHECK: define linkonce_odr noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
// CHECK: define linkonce_odr noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv

// MSVC: define linkonce_odr dso_local void @"??$f@V<lambda_1>@dg_inline1@QL@@@@YAXV<lambda_1>@dg_inline1@QL@@@Z"
// MSVC: call noundef i32 @"??R<lambda_1>@dg_inline1@QL@@QEBA?A?<auto>@@XZ"
// MSVC: define linkonce_odr dso_local void @"??$f@V<lambda_1>@?$dg_template@$02@QL@@@@YAXV<lambda_1>@?$dg_template@$02@QL@@@Z"
// MSVC: call noundef i32 @"??R<lambda_1>@?$dg_template@$02@QL@@QEBA?A?<auto>@@XZ"
// MSVC: define internal noundef i32 @"??R<lambda_0>@QL@@QEBA?A?<auto>@@XZ"
// MSVC: define internal noundef i32 @"??R<lambda_1>@QL@@QEBA?A?<auto>@@XZ"
// MSVC: define linkonce_odr dso_local noundef i32 @"??R<lambda_1>@dg_inline1@QL@@QEBA?A?<auto>@@XZ"
// MSVC: define linkonce_odr dso_local noundef i32 @"??R<lambda_1>@?$dg_template@$02@QL@@QEBA?A?<auto>@@XZ"
4 changes: 2 additions & 2 deletions clang/test/CodeGenCUDA/anon-ns.cu
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@

// HIP-DAG: define weak_odr {{.*}}void @[[KERN:_ZN12_GLOBAL__N_16kernelEv\.intern\.b04fd23c98500190]](
// HIP-DAG: define weak_odr {{.*}}void @[[KTX:_Z2ktIN12_GLOBAL__N_11XEEvT_\.intern\.b04fd23c98500190]](
// HIP-DAG: define weak_odr {{.*}}void @[[KTL:_Z2ktIN12_GLOBAL__N_1UlvE_EEvT_\.intern\.b04fd23c98500190]](
// HIP-DAG: define weak_odr {{.*}}void @[[KTL:_Z2ktIN12_GLOBAL__N_16lambdaMUlvE_EEvT_.intern\.b04fd23c98500190]](
// HIP-DAG: @[[VM:_ZN12_GLOBAL__N_12vmE\.static\.b04fd23c98500190]] = addrspace(1) externally_initialized global
// HIP-DAG: @[[VC:_ZN12_GLOBAL__N_12vcE\.static\.b04fd23c98500190]] = addrspace(4) externally_initialized constant
// HIP-DAG: @[[VT:_Z2vtIN12_GLOBAL__N_11XEE\.static\.b04fd23c98500190]] = addrspace(1) externally_initialized global

// CUDA-DAG: define weak_odr {{.*}}void @[[KERN:_ZN12_GLOBAL__N_16kernelEv__intern__b04fd23c98500190]](
// CUDA-DAG: define weak_odr {{.*}}void @[[KTX:_Z2ktIN12_GLOBAL__N_11XEEvT___intern__b04fd23c98500190]](
// CUDA-DAG: define weak_odr {{.*}}void @[[KTL:_Z2ktIN12_GLOBAL__N_1UlvE_EEvT___intern__b04fd23c98500190]](
// CUDA-DAG: define weak_odr {{.*}}void @[[KTL:_Z2ktIN12_GLOBAL__N_16lambdaMUlvE_EEvT___intern__b04fd23c98500190]](
// CUDA-DAG: @[[VC:_ZN12_GLOBAL__N_12vcE__static__b04fd23c98500190]] = addrspace(4) externally_initialized constant
// CUDA-DAG: @[[VT:_Z2vtIN12_GLOBAL__N_11XEE__static__b04fd23c98500190]] = addrspace(1) externally_initialized global

Expand Down
74 changes: 74 additions & 0 deletions clang/test/CodeGenSYCL/unnamed-types.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// RUN: %clang_cc1 -fsycl-is-device -O0 -triple spirv64-unknown-unknown \
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=DEVICE

// RUN: %clang_cc1 -fsycl-is-host -O0 -triple spirv64-unknown-unknown \
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=HOST

// RUN: %clang_cc1 -fsycl-is-device -emit-llvm \
// RUN: -aux-triple x86_64-pc-windows-msvc -triple spir64-unknown--unknown \
// RUN: %s -o - | FileCheck %s --check-prefix=MSVC

namespace QL {
auto dg1 = [] { return 1; };
inline auto dg_inline1 = [] { return 1; };
}

namespace QL {
auto dg2 = [] { return 2; };
template<int N>
auto dg_template = [] { return N; };
}

using namespace QL;
template<typename T>
[[clang::sycl_kernel_entry_point(T)]] void f(T t) {
t();
}

void g() {
f(dg1);
f(dg2);
f(dg_inline1);
f(dg_template<3>);
}

// HOST: @_ZN2QL3dg1E = internal global %class.anon undef, align 1
// HOST: @_ZN2QL3dg2E = internal global %class.anon.0 undef, align 1
// HOST: @_ZN2QL10dg_inline1E = linkonce_odr global %class.anon.2 undef, comdat, align 1
// HOST: @_ZN2QL11dg_templateILi3EEE = linkonce_odr global %class.anon.4 undef, comdat, align 1

// DEVICE: define spir_kernel void @_ZTSN2QL3dg1MUlvE_E
// DEVICE: call spir_func noundef i32 @_ZNK2QL3dg1MUlvE_clEv
// DEVICE: define internal spir_func noundef i32 @_ZNK2QL3dg1MUlvE_clEv
// DEVICE: define spir_kernel void @_ZTSN2QL3dg2MUlvE_E
// DEVICE: call spir_func noundef i32 @_ZNK2QL3dg2MUlvE_clEv
// DEVICE: define internal spir_func noundef i32 @_ZNK2QL3dg2MUlvE_clEv
// DEVICE: define spir_kernel void @_ZTSN2QL10dg_inline1MUlvE_E
// DEVICE: call spir_func noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
// DEVICE: define linkonce_odr spir_func noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
// DEVICE: define spir_kernel void @_ZTSN2QL11dg_templateILi3EEMUlvE_E
// DEVICE: call spir_func noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv
// DEVICE: define linkonce_odr spir_func noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv

// HOST: define spir_func void @_Z1gv
// HOST: call spir_func void @_Z1fIN2QL3dg1MUlvE_EEvT_
// HOST: call spir_func void @_Z1fIN2QL3dg2MUlvE_EEvT_
// HOST: call spir_func void @_Z1fIN2QL10dg_inline1MUlvE_EEvT_
// HOST: call spir_func void @_Z1fIN2QL11dg_templateILi3EEMUlvE_EEvT_
// HOST: define internal spir_func void @_Z1fIN2QL3dg1MUlvE_EEvT
// HOST: define internal spir_func void @_Z1fIN2QL3dg2MUlvE_EEvT_
// HOST: define linkonce_odr spir_func void @_Z1fIN2QL10dg_inline1MUlvE_EEvT_
// HOST: define linkonce_odr spir_func void @_Z1fIN2QL11dg_templateILi3EEMUlvE_EEvT_

// MSVC: define dso_local spir_kernel void @_ZTSN2QL3dg1MUlvE_E
// MSVC: call spir_func noundef i32 @_ZNK2QL3dg1MUlvE_clEv
// MSVC: define internal spir_func noundef i32 @_ZNK2QL3dg1MUlvE_clEv
// MSVC: define dso_local spir_kernel void @_ZTSN2QL3dg2MUlvE_E
// MSVC: call spir_func noundef i32 @_ZNK2QL3dg2MUlvE_clEv
// MSVC: define internal spir_func noundef i32 @_ZNK2QL3dg2MUlvE_clEv
// MSVC: define dso_local spir_kernel void @_ZTSN2QL10dg_inline1MUlvE_E
// MSVC: call spir_func noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
// MSVC: define linkonce_odr spir_func noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
// MSVC: define dso_local spir_kernel void @_ZTSN2QL11dg_templateILi3EEMUlvE_E
// MSVC: call spir_func noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv
// MSVC: define linkonce_odr spir_func noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv
Loading