Our current implementation of string lowering did some work to remove extra trailing zeros, plus do a 'zero' constant. That is unchanged by this patch. However, this patch ALSO ensures that we do the 'remove extra trailing zeros' to remove ALL trailing zeros, which likely has canonicalization benefits later on. However, the real benefit of this patch is to make string emission by default emit a null-terminator, which fixes the virtual table 'name' field get lowered correctly. We do this by making the builder::getString function take an argument (true by default) that will ensure we add a null terminator if necessary. This reflects the llvm::ConstantDataArray::getString function, which has the same functionality. However, doing this during lowering seems incorrect, since the FE is the one that knows whether these null terminators are necessary. There is not currently an 'opt out' use of the behavior, but the functionality is left in place to better reflect the ConstantDataArray::getString function interface. Note with the tests that this fixes some inconsistencies between LLVM and OGCG lowering.
88 lines
5.4 KiB
C
88 lines
5.4 KiB
C
// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -o %t.cir
|
|
// RUN: FileCheck %s --input-file=%t.cir --check-prefix=CIR
|
|
// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -o %t-cir.ll
|
|
// RUN: FileCheck %s --input-file=%t-cir.ll --check-prefix=LLVM
|
|
// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -o %t.ll
|
|
// RUN: FileCheck %s --input-file=%t.ll --check-prefix=OGCG
|
|
|
|
// CIR: cir.global "private" internal dso_local @staticFuncName.name = #cir.global_view<@".str.4"> : !cir.ptr<!s8i> {alignment = 8 : i64} loc(#loc1)
|
|
// CIR: cir.global "private" constant cir_private dso_local @".str" = #cir.zero : !cir.array<!s8i x 1>
|
|
// CIR: cir.global external @func = #cir.global_view<@".str"> : !cir.ptr<!s8i>
|
|
// CIR: cir.global "private" constant cir_private dso_local @__func__.plainFunction = #cir.const_array<"plainFunction" : !cir.array<!s8i x 13>, trailing_zeros>
|
|
// CIR: cir.global "private" constant cir_private dso_local @__PRETTY_FUNCTION__.plainFunction = #cir.const_array<"void plainFunction(void)" : !cir.array<!s8i x 24>, trailing_zeros>
|
|
// CIR: cir.global "private" constant cir_private dso_local @__func__.externFunction = #cir.const_array<"externFunction" : !cir.array<!s8i x 14>, trailing_zeros>
|
|
// CIR: cir.global "private" constant cir_private dso_local @__PRETTY_FUNCTION__.externFunction = #cir.const_array<"void externFunction(void)" : !cir.array<!s8i x 25>, trailing_zeros>
|
|
// CIR: cir.global "private" constant cir_private dso_local @__func__.privateExternFunction = #cir.const_array<"privateExternFunction" : !cir.array<!s8i x 21>, trailing_zeros>
|
|
// CIR: cir.global "private" constant cir_private dso_local @__PRETTY_FUNCTION__.privateExternFunction = #cir.const_array<"void privateExternFunction(void)" : !cir.array<!s8i x 32>, trailing_zeros>
|
|
// CIR: cir.global "private" constant cir_private dso_local @".str.4" = #cir.const_array<"staticFuncName" : !cir.array<!s8i x 14>, trailing_zeros> : !cir.array<!s8i x 15>
|
|
// CIR: cir.global "private" constant cir_private dso_local @__func__.staticFunction = #cir.const_array<"staticFunction" : !cir.array<!s8i x 14>, trailing_zeros>
|
|
// CIR: cir.global "private" constant cir_private dso_local @__PRETTY_FUNCTION__.staticFunction = #cir.const_array<"void staticFunction(void)" : !cir.array<!s8i x 25>, trailing_zeros>
|
|
|
|
// TODO(cir): These should be unnamed_addr
|
|
// LLVM: @staticFuncName.name = internal global ptr @.str.4, align 8
|
|
// LLVM: @.str = private constant [1 x i8] zeroinitializer, align 1
|
|
// LLVM: @func = global ptr @.str, align 8
|
|
// LLVM: @__func__.plainFunction = private constant [14 x i8] c"plainFunction\00"
|
|
// LLVM: @__PRETTY_FUNCTION__.plainFunction = private constant [25 x i8] c"void plainFunction(void)\00"
|
|
// LLVM: @__func__.externFunction = private constant [15 x i8] c"externFunction\00"
|
|
// LLVM: @__PRETTY_FUNCTION__.externFunction = private constant [26 x i8] c"void externFunction(void)\00"
|
|
// LLVM: @__func__.privateExternFunction = private constant [22 x i8] c"privateExternFunction\00"
|
|
// LLVM: @__PRETTY_FUNCTION__.privateExternFunction = private constant [33 x i8] c"void privateExternFunction(void)\00"
|
|
// LLVM: @__func__.staticFunction = private constant [15 x i8] c"staticFunction\00"
|
|
// LLVM: @__PRETTY_FUNCTION__.staticFunction = private constant [26 x i8] c"void staticFunction(void)\00"
|
|
|
|
// OGCG: @.str = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
|
// OGCG: @func = global ptr @.str, align 8
|
|
// OGCG: @__func__.plainFunction = private unnamed_addr constant [14 x i8] c"plainFunction\00"
|
|
// OGCG: @__PRETTY_FUNCTION__.plainFunction = private unnamed_addr constant [25 x i8] c"void plainFunction(void)\00"
|
|
// OGCG: @__func__.externFunction = private unnamed_addr constant [15 x i8] c"externFunction\00"
|
|
// OGCG: @__PRETTY_FUNCTION__.externFunction = private unnamed_addr constant [26 x i8] c"void externFunction(void)\00"
|
|
// OGCG: @__func__.privateExternFunction = private unnamed_addr constant [22 x i8] c"privateExternFunction\00"
|
|
// OGCG: @__PRETTY_FUNCTION__.privateExternFunction = private unnamed_addr constant [33 x i8] c"void privateExternFunction(void)\00"
|
|
// OGCG: @staticFuncName.name = internal global ptr @.str.4, align 8
|
|
// OGCG: @__func__.staticFunction = private unnamed_addr constant [15 x i8] c"staticFunction\00"
|
|
// OGCG: @__PRETTY_FUNCTION__.staticFunction = private unnamed_addr constant [26 x i8] c"void staticFunction(void)\00"
|
|
|
|
const char* func = __func__;
|
|
|
|
int printf(const char *, ...);
|
|
|
|
void plainFunction(void) {
|
|
printf("__func__ %s\n", __func__);
|
|
printf("__FUNCTION__ %s\n", __FUNCTION__);
|
|
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
|
}
|
|
|
|
extern void externFunction(void) {
|
|
printf("__func__ %s\n", __func__);
|
|
printf("__FUNCTION__ %s\n", __FUNCTION__);
|
|
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
|
}
|
|
|
|
__private_extern__ void privateExternFunction(void) {
|
|
printf("__func__ %s\n", __func__);
|
|
printf("__FUNCTION__ %s\n", __FUNCTION__);
|
|
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
|
}
|
|
|
|
// TODO(cir): Add support for __captured_stmt
|
|
|
|
static void staticFunction(void) {
|
|
printf("__func__ %s\n", __func__);
|
|
printf("__FUNCTION__ %s\n", __FUNCTION__);
|
|
printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
|
|
}
|
|
|
|
void staticFuncName(void) {
|
|
static const char *name = __func__;
|
|
}
|
|
|
|
int main(void) {
|
|
plainFunction();
|
|
externFunction();
|
|
privateExternFunction();
|
|
staticFunction();
|
|
staticFuncName();
|
|
return 0;
|
|
}
|