[libc-commits] [libc] e4693c0 - [libc] Add __isoc99_fscanf alias. (#213125)
via libc-commits
libc-commits at lists.llvm.org
Sun Aug 2 08:13:22 PDT 2026
Author: lntue
Date: 2026-08-02T11:13:17-04:00
New Revision: e4693c0579ed0f3df45a06b918d448795b738a58
URL: https://github.com/llvm/llvm-project/commit/e4693c0579ed0f3df45a06b918d448795b738a58
DIFF: https://github.com/llvm/llvm-project/commit/e4693c0579ed0f3df45a06b918d448795b738a58.diff
LOG: [libc] Add __isoc99_fscanf alias. (#213125)
- Add LLVM_LIBC_ADD_FUNCTION_C_ALIAS macro to add another C alias public
symbol to a function.
- Add LIBC_CONF_SCANF_PROVIDE_ISOC99_ALIASES config
- Add __isoc99_fscanf for generic fscanf target if
LIBC_CONF_SCANF_PROVIDE_ISOC99_ALIASES is set.
- Similarly: scanf, vfscanf, vscanf.
Added:
Modified:
libc/CMakeLists.txt
libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
libc/cmake/modules/LibcConfig.cmake
libc/config/config.json
libc/config/linux/config.json
libc/src/__support/common.h
libc/src/stdio/generic/fscanf.cpp
libc/src/stdio/generic/scanf.cpp
libc/src/stdio/generic/vfscanf.cpp
libc/src/stdio/generic/vscanf.cpp
libc/src/stdio/sscanf.cpp
libc/src/stdio/vsscanf.cpp
Removed:
################################################################################
diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index c5dea3100f053..7e42ba2a76df2 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -152,6 +152,11 @@ if(LIBC_TARGET_OS_IS_GPU)
endif()
option(LLVM_LIBC_FULL_BUILD "Build and test LLVM libc as if it is the full libc" ${default_to_full_build})
+if(LLVM_LIBC_FULL_BUILD)
+ set(LLVM_LIBC_OVERLAY OFF)
+else()
+ set(LLVM_LIBC_OVERLAY ON)
+endif()
option(LLVM_LIBC_IMPLEMENTATION_DEFINED_TEST_BEHAVIOR "Build LLVM libc tests assuming our implementation-defined behavior" ON)
option(LLVM_LIBC_ENABLE_LINTING "Enables linting of libc source files" OFF)
option(LLVM_LIBC_ALL_HEADERS "Outputs all functions in header files, regardless of whether they are enabled on this target" OFF)
diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index 600df74f552b0..4f8f3f5d13b82 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -193,6 +193,10 @@ function(_get_compile_options_from_config output_var)
list(APPEND config_options "-DLIBC_COPT_USE_C_ASSERT")
endif()
+ if(LIBC_CONF_SCANF_PROVIDE_ISOC99_ALIASES)
+ list(APPEND config_options "-DLIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES")
+ endif()
+
set(${output_var} ${config_options} PARENT_SCOPE)
endfunction(_get_compile_options_from_config)
diff --git a/libc/cmake/modules/LibcConfig.cmake b/libc/cmake/modules/LibcConfig.cmake
index 19bdf44d96bfc..dd6e3cf49375c 100644
--- a/libc/cmake/modules/LibcConfig.cmake
+++ b/libc/cmake/modules/LibcConfig.cmake
@@ -37,7 +37,9 @@ function(read_libc_config config_file opt_list)
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
PROPERTY CMAKE_CONFIGURE_DEPENDS ${config_file})
- file(READ ${config_file} json_config)
+ file(READ ${config_file} json_config_raw)
+ # Expand all CMake variables in the JSON string first
+ string(CONFIGURE "${json_config_raw}" json_config)
string(JSON group_count ERROR_VARIABLE json_error LENGTH ${json_config})
if(json_error)
message(FATAL_ERROR "${config_file}: ${json_error}")
diff --git a/libc/config/config.json b/libc/config/config.json
index d576d7d14e4af..01909fb9abf8a 100644
--- a/libc/config/config.json
+++ b/libc/config/config.json
@@ -73,6 +73,10 @@
"LIBC_CONF_SCANF_DISABLE_INDEX_MODE": {
"value": false,
"doc": "Disable index mode in the scanf format string."
+ },
+ "LIBC_CONF_SCANF_PROVIDE_ISOC99_ALIASES": {
+ "value": false,
+ "doc": "Add __isoc99_* aliases for scanf's functions."
}
},
"str_to_float": {
diff --git a/libc/config/linux/config.json b/libc/config/linux/config.json
index a3676986721b4..260ec3b43f72c 100644
--- a/libc/config/linux/config.json
+++ b/libc/config/linux/config.json
@@ -1,4 +1,9 @@
{
+ "scanf": {
+ "LIBC_CONF_SCANF_PROVIDE_ISOC99_ALIASES": {
+ "value": "${LLVM_LIBC_OVERLAY}"
+ }
+ },
"string": {
"LIBC_CONF_STRING_LENGTH_IMPL": {
"value": "clang_vector"
diff --git a/libc/src/__support/common.h b/libc/src/__support/common.h
index 8a8ffefd381ee..e142eb815f2fa 100644
--- a/libc/src/__support/common.h
+++ b/libc/src/__support/common.h
@@ -61,17 +61,33 @@
__##name##_impl__ asm(c_alias); \
decltype(LIBC_NAMESPACE::name) name [[gnu::alias(c_alias)]]; \
type __##name##_impl__ arglist
+
+#define LLVM_LIBC_ADD_FUNCTION_C_ALIAS(name, c_alias) \
+ extern "C" decltype(LIBC_NAMESPACE::name) c_alias [[gnu::alias(#name)]]
+
#else // LIBC_TARGET_USES_LEADING_UNDERSCORE
#define LLVM_LIBC_FUNCTION_IMPL_4(type, name, arglist, c_alias) \
LLVM_LIBC_ATTR(name) \
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) name asm( \
"_" c_alias); \
type name arglist
+
+// clang-format off
+#define LLVM_LIBC_ADD_FUNCTION_C_ALIAS(name, c_alias) \
+ asm(".text\n" \
+ ".global " "_" #c_alias "\n" \
+ ".type " "_" #c_alias ", @function\n" \
+ "_" #c_alias " = " "_" #name "\n")
+// clang-format on
#endif // LIBC_TARGET_USES_LEADING_UNDERSCORE
#else // LIBC_COPT_PUBLIC_PACKAGING
#define LLVM_LIBC_FUNCTION_IMPL_4(type, name, arglist, c_alias) \
type name arglist
+
+#define LLVM_LIBC_ADD_FUNCTION_C_ALIAS(name, c_alias) \
+ static_assert(true, "Require semicolon.")
+
#endif // LIBC_COPT_PUBLIC_PACKAGING
#define LLVM_LIBC_FUNCTION_IMPL_3(type, name, arglist) \
diff --git a/libc/src/stdio/generic/fscanf.cpp b/libc/src/stdio/generic/fscanf.cpp
index 94b843978749e..f0f6c627b5054 100644
--- a/libc/src/stdio/generic/fscanf.cpp
+++ b/libc/src/stdio/generic/fscanf.cpp
@@ -34,3 +34,7 @@ LLVM_LIBC_FUNCTION(int, fscanf,
}
} // namespace LIBC_NAMESPACE_DECL
+
+#ifdef LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
+LLVM_LIBC_ADD_FUNCTION_C_ALIAS(fscanf, __isoc99_fscanf);
+#endif // LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
diff --git a/libc/src/stdio/generic/scanf.cpp b/libc/src/stdio/generic/scanf.cpp
index 37b7ee7d7ca36..f0607c6c8b6ab 100644
--- a/libc/src/stdio/generic/scanf.cpp
+++ b/libc/src/stdio/generic/scanf.cpp
@@ -40,3 +40,7 @@ LLVM_LIBC_FUNCTION(int, scanf, (const char *__restrict format, ...)) {
}
} // namespace LIBC_NAMESPACE_DECL
+
+#ifdef LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
+LLVM_LIBC_ADD_FUNCTION_C_ALIAS(scanf, __isoc99_scanf);
+#endif // LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
diff --git a/libc/src/stdio/generic/vfscanf.cpp b/libc/src/stdio/generic/vfscanf.cpp
index 220576522d0fd..5976e61b857c5 100644
--- a/libc/src/stdio/generic/vfscanf.cpp
+++ b/libc/src/stdio/generic/vfscanf.cpp
@@ -32,3 +32,7 @@ LLVM_LIBC_FUNCTION(int, vfscanf,
}
} // namespace LIBC_NAMESPACE_DECL
+
+#ifdef LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
+LLVM_LIBC_ADD_FUNCTION_C_ALIAS(vfscanf, __isoc99_vfscanf);
+#endif // LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
diff --git a/libc/src/stdio/generic/vscanf.cpp b/libc/src/stdio/generic/vscanf.cpp
index 215ba790b241c..ea82c5edb729a 100644
--- a/libc/src/stdio/generic/vscanf.cpp
+++ b/libc/src/stdio/generic/vscanf.cpp
@@ -39,3 +39,7 @@ LLVM_LIBC_FUNCTION(int, vscanf,
}
} // namespace LIBC_NAMESPACE_DECL
+
+#ifdef LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
+LLVM_LIBC_ADD_FUNCTION_C_ALIAS(vscanf, __isoc99_vscanf);
+#endif // LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
diff --git a/libc/src/stdio/sscanf.cpp b/libc/src/stdio/sscanf.cpp
index 9fa2ede461595..85f7a3a2869f5 100644
--- a/libc/src/stdio/sscanf.cpp
+++ b/libc/src/stdio/sscanf.cpp
@@ -37,3 +37,7 @@ LLVM_LIBC_FUNCTION(int, sscanf,
}
} // namespace LIBC_NAMESPACE_DECL
+
+#ifdef LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
+LLVM_LIBC_ADD_FUNCTION_C_ALIAS(sscanf, __isoc99_sscanf);
+#endif // LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
diff --git a/libc/src/stdio/vsscanf.cpp b/libc/src/stdio/vsscanf.cpp
index 7c7240a102b5a..f46754a48e97a 100644
--- a/libc/src/stdio/vsscanf.cpp
+++ b/libc/src/stdio/vsscanf.cpp
@@ -29,3 +29,7 @@ LLVM_LIBC_FUNCTION(int, vsscanf,
}
} // namespace LIBC_NAMESPACE_DECL
+
+#ifdef LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
+LLVM_LIBC_ADD_FUNCTION_C_ALIAS(vsscanf, __isoc99_vsscanf);
+#endif // LIBC_COPT_SCANF_PROVIDE_ISOC99_ALIASES
More information about the libc-commits
mailing list