[clang] Improve clarity of the implicit declaration diagnostic (PR #149314)
Oliver Hunt via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 7 02:27:01 PDT 2025
================
@@ -376,6 +376,33 @@ class Context {
return getInfo(ID).Header.getName();
}
+ /// Returns true if a library function is declared within a C or C++ standard
+ /// header (like stdio.h) or POSIX header (like malloc.h), false if the
+ /// function is not declared within a header or is declared in a non-standard
+ /// header (like Microsoft or Objective-C headers).
+ bool isDeclaredInStandardHeader(unsigned ID) const {
+ switch (getInfo(ID).Header.ID) {
+ default:
+ return false;
+ case HeaderDesc::COMPLEX_H: // C99
+ case HeaderDesc::CTYPE_H: // C89
+ case HeaderDesc::MATH_H: // C89
+ case HeaderDesc::MALLOC_H: // POSIX
+ case HeaderDesc::MEMORY: // C++98
+ case HeaderDesc::PTHREAD_H: // POSIX
+ case HeaderDesc::SETJMP_H: // C89
+ case HeaderDesc::STDARG_H: // C89
+ case HeaderDesc::STDIO_H: // C89
+ case HeaderDesc::STDLIB_H: // C89
+ case HeaderDesc::STRING_H: // C89
+ case HeaderDesc::STRINGS_H: // POSIX
+ case HeaderDesc::UNISTD_H: // POSIX
+ case HeaderDesc::UTILITY: // C++98
+ case HeaderDesc::WCHAR_H: // C99
+ return true;
+ }
+ }
----------------
ojhunt wrote:
Something like this would do it:
```diff
diff --git a/clang/include/clang/Basic/BuiltinHeaders.def b/clang/include/clang/Basic/BuiltinHeaders.def
index 8e4a2f9bee9a..bcbf15fdc91f 100644
--- a/clang/include/clang/Basic/BuiltinHeaders.def
+++ b/clang/include/clang/Basic/BuiltinHeaders.def
@@ -11,33 +11,33 @@
//
//===----------------------------------------------------------------------===//
-HEADER(NO_HEADER, nullptr)
-HEADER(BLOCKS_H, "Blocks.h")
-HEADER(COMPLEX_H, "complex.h")
-HEADER(CTYPE_H, "ctype.h")
-HEADER(EMMINTRIN_H, "emmintrin.h")
-HEADER(FOUNDATION_NSOBJCRUNTIME_H, "Foundation/NSObjCRuntime.h")
-HEADER(IMMINTRIN_H, "immintrin.h")
-HEADER(INTRIN_H, "intrin.h")
-HEADER(MALLOC_H, "malloc.h")
-HEADER(MATH_H, "math.h")
-HEADER(MEMORY, "memory")
-HEADER(OBJC_MESSAGE_H, "objc/message.h")
-HEADER(OBJC_OBJC_AUTO_H, "objc/objc-auto.h")
-HEADER(OBJC_OBJC_EXCEPTION_H, "objc/objc-exception.h")
-HEADER(OBJC_OBJC_SYNC_H, "objc/objc-sync.h")
-HEADER(OBJC_RUNTIME_H, "objc/runtime.h")
-HEADER(PTHREAD_H, "pthread.h")
-HEADER(SETJMPEX_H, "setjmpex.h")
-HEADER(SETJMP_H, "setjmp.h")
-HEADER(STDARG_H, "stdarg.h")
-HEADER(STDIO_H, "stdio.h")
-HEADER(STDLIB_H, "stdlib.h")
-HEADER(STRINGS_H, "strings.h")
-HEADER(STRING_H, "string.h")
-HEADER(UNISTD_H, "unistd.h")
-HEADER(UTILITY, "utility")
-HEADER(WCHAR_H, "wchar.h")
-HEADER(XMMINTRIN_H, "xmmintrin.h")
+HEADER(NO_HEADER, nullptr, false)
+HEADER(BLOCKS_H, "Blocks.h", false)
+HEADER(COMPLEX_H, "complex.h", true)
+HEADER(CTYPE_H, "ctype.h", true)
+HEADER(EMMINTRIN_H, "emmintrin.h", false)
+HEADER(FOUNDATION_NSOBJCRUNTIME_H, "Foundation/NSObjCRuntime.h", false)
+HEADER(IMMINTRIN_H, "immintrin.h", false)
+HEADER(INTRIN_H, "intrin.h", false)
+HEADER(MALLOC_H, "malloc.h", true)
+HEADER(MATH_H, "math.h", true)
+HEADER(MEMORY, "memory", true)
+HEADER(OBJC_MESSAGE_H, "objc/message.h", false)
+HEADER(OBJC_OBJC_AUTO_H, "objc/objc-auto.h", false)
+HEADER(OBJC_OBJC_EXCEPTION_H, "objc/objc-exception.h", false)
+HEADER(OBJC_OBJC_SYNC_H, "objc/objc-sync.h", false)
+HEADER(OBJC_RUNTIME_H, "objc/runtime.h", false)
+HEADER(PTHREAD_H, "pthread.h", true)
+HEADER(SETJMPEX_H, "setjmpex.h", false)
+HEADER(SETJMP_H, "setjmp.h", true)
+HEADER(STDARG_H, "stdarg.h", true)
+HEADER(STDIO_H, "stdio.h", true)
+HEADER(STDLIB_H, "stdlib.h", true)
+HEADER(STRINGS_H, "strings.h", true)
+HEADER(STRING_H, "string.h", true)
+HEADER(UNISTD_H, "unistd.h", true)
+HEADER(UTILITY, "utility", true)
+HEADER(WCHAR_H, "wchar.h", true)
+HEADER(XMMINTRIN_H, "xmmintrin.h", false)
#undef HEADER
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index f955d2116955..3847c0cb7481 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -50,7 +50,7 @@ enum LanguageID : uint16_t {
struct HeaderDesc {
enum HeaderID : uint16_t {
-#define HEADER(ID, NAME) ID,
+#define HEADER(ID, NAME, IS_STANDARD_HEADER) ID,
#include "clang/Basic/BuiltinHeaders.def"
#undef HEADER
} ID;
@@ -222,6 +222,19 @@ public:
const char *getHeaderName(unsigned ID) const {
return getRecord(ID).Header.getName();
}
+ /// Returns true if a library function is declared within a C or C++ standard
+ /// header (like stdio.h) or POSIX header (like malloc.h), false if the
+ /// function is not declared within a header or is declared in a non-standard
+ /// header (like Microsoft or Objective-C headers).
+ bool isDeclaredInStandardHeader(unsigned ID) const {
+ switch (getInfo(ID).Header.ID) {
+#define HEADER(ID, NAME, IS_STANDARD_HEADER) \
+ case ID: \
+ return IS_STANDARD_HEADER;
+#include "clang/Basic/BuiltinHeaders.def"
+#undef HEADER
+ };
+ }
/// Determine whether this builtin is like printf in its
/// formatting rules and, if so, set the index to the format string
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index b116abbe034f..a5cb80067a4e 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -20,7 +20,7 @@ using namespace clang;
const char *HeaderDesc::getName() const {
switch (ID) {
-#define HEADER(ID, NAME) \
+#define HEADER(ID, NAME, IS_STANDARD_HEADER) \
case ID: \
return NAME;
#include "clang/Basic/BuiltinHeaders.def"
```
https://github.com/llvm/llvm-project/pull/149314
More information about the cfe-commits
mailing list