How __func__ keyword in C translated in LLVM?

Dec. 31, 2024

__func__ is implemented as global variable determined in compile-time.

I checked it by testing with simple example.

Example code:

#include <stdio.h>

int foo(){
    printf("%s", __func__);
}

int main(){
    printf("%s", __func__);
}

Translated LLVM IR:

; ModuleID = 'print_func.bc'
source_filename = "llvm-link"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

@.str = private unnamed_addr constant [3 x i8] c"%s\00", align 1
@__func__.foo = private unnamed_addr constant [4 x i8] c"foo\00", align 1
@__func__.main = private unnamed_addr constant [5 x i8] c"main\00", align 1

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @foo() #0 {
  %1 = alloca i32, align 4
  %2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @__func__.foo, i64 0, i64 0))
  %3 = load i32, i32* %1, align 4
  ret i32 %3
}

declare dso_local i32 @printf(i8*, ...) #1

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
  %1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @__func__.main, i64 0, i64 0))
  ret i32 0
}

We can find the globals which correspond to __func__ as follows.

@.str = private unnamed_addr constant [3 x i8] c"%s\00", align 1
@__func__.foo = private unnamed_addr constant [4 x i8] c"foo\00", align 1
@__func__.main = private unnamed_addr constant [5 x i8] c"main\00", align 1