[clang] clang: Make the type_info builtin declaration a singleton (PR #151277)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 29 23:47:13 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-modules
Author: Matt (matts1)
<details>
<summary>Changes</summary>
This fixes an ambiguous type type_info when you try and reference the `type_info` type while using clang modulemaps with `-fms-compatibility` enabled
Fixes #<!-- -->38400
---
Full diff: https://github.com/llvm/llvm-project/pull/151277.diff
6 Files Affected:
- (modified) clang/include/clang/AST/ASTContext.h (+12)
- (modified) clang/include/clang/AST/DeclID.h (+3)
- (modified) clang/lib/Sema/Sema.cpp (+1-3)
- (modified) clang/lib/Serialization/ASTReader.cpp (+3)
- (modified) clang/lib/Serialization/ASTWriter.cpp (+2)
- (added) clang/test/Modules/pr151277.cpp (+15)
``````````diff
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 0273109f8a698..3d70654314939 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1290,6 +1290,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
// Implicitly-declared type 'struct _GUID'.
mutable TagDecl *MSGuidTagDecl = nullptr;
+ // Implicitly-declared type 'struct type_info'.
+ mutable TagDecl *MSTypeInfoTagDecl = nullptr;
+
/// Keep track of CUDA/HIP device-side variables ODR-used by host code.
/// This does not include extern shared variables used by device host
/// functions as addresses of shared variables are per warp, therefore
@@ -2381,6 +2384,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
return getTagDeclType(MSGuidTagDecl);
}
+ /// Retrieve the implicitly-predeclared 'struct type_info' declaration.
+ TagDecl *getMSTypeInfoTagDecl() const {
+ // Lazily create this type on demand - it's only needed for MS builds.
+ if (!MSTypeInfoTagDecl) {
+ MSTypeInfoTagDecl = buildImplicitRecord("type_info");
+ }
+ return MSTypeInfoTagDecl;
+ }
+
/// Return whether a declaration to a builtin is allowed to be
/// overloaded/redeclared.
bool canBuiltinBeRedeclared(const FunctionDecl *) const;
diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h
index 384f7b031e007..47ae05b2747ae 100644
--- a/clang/include/clang/AST/DeclID.h
+++ b/clang/include/clang/AST/DeclID.h
@@ -77,6 +77,9 @@ enum PredefinedDeclIDs {
/// The internal '__NSConstantString' tag type.
PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID,
+ /// The predeclared 'type_info' struct.
+ PREDEF_DECL_BUILTIN_MS_TYPE_INFO_TAG_ID,
+
#define BuiltinTemplate(BTName) PREDEF_DECL##BTName##_ID,
#include "clang/Basic/BuiltinTemplates.inc"
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index d50eeff0e4b3b..a1f707e601db3 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -443,9 +443,7 @@ void Sema::Initialize() {
if (getLangOpts().MSVCCompat) {
if (getLangOpts().CPlusPlus &&
IdResolver.begin(&Context.Idents.get("type_info")) == IdResolver.end())
- PushOnScopeChains(
- Context.buildImplicitRecord("type_info", TagTypeKind::Class),
- TUScope);
+ PushOnScopeChains(Context.getMSTypeInfoTagDecl(), TUScope);
addImplicitTypedef("size_t", Context.getSizeType());
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index f896f9f11c2b3..44b48b9b4711a 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -8318,6 +8318,9 @@ Decl *ASTReader::getPredefinedDecl(PredefinedDeclIDs ID) {
NewLoaded = Context.getCFConstantStringTagDecl();
break;
+ case PREDEF_DECL_BUILTIN_MS_TYPE_INFO_TAG_ID:
+ return Context.getMSTypeInfoTagDecl();
+
#define BuiltinTemplate(BTName) \
case PREDEF_DECL##BTName##_ID: \
if (Context.Decl##BTName) \
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index a6957e54b66f1..2b40be3b7349d 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5618,6 +5618,8 @@ void ASTWriter::PrepareWritingSpecialDecls(Sema &SemaRef) {
PREDEF_DECL_BUILTIN_MS_VA_LIST_ID);
RegisterPredefDecl(Context.MSGuidTagDecl,
PREDEF_DECL_BUILTIN_MS_GUID_ID);
+ RegisterPredefDecl(Context.MSTypeInfoTagDecl,
+ PREDEF_DECL_BUILTIN_MS_TYPE_INFO_TAG_ID);
RegisterPredefDecl(Context.ExternCContext, PREDEF_DECL_EXTERN_C_CONTEXT_ID);
RegisterPredefDecl(Context.CFConstantStringTypeDecl,
PREDEF_DECL_CF_CONSTANT_STRING_ID);
diff --git a/clang/test/Modules/pr151277.cpp b/clang/test/Modules/pr151277.cpp
new file mode 100644
index 0000000000000..2428e854d6edf
--- /dev/null
+++ b/clang/test/Modules/pr151277.cpp
@@ -0,0 +1,15 @@
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -I%t -emit-module -o %t/a.pcm -fmodules %t/module.modulemap -fno-implicit-modules -fmodule-name=a -x c++-header -fms-compatibility
+// RUN: %clang_cc1 -I%t -emit-module -o %t/b.pcm -fmodules %t/module.modulemap -fno-implicit-modules -fmodule-name=b -x c++-header -fms-compatibility -fmodule-file=%t/a.pcm
+
+//--- module.modulemap
+module a { header "a.h" }
+module b { header "b.h" }
+
+//--- a.h
+type_info* foo;
+
+//--- b.h
+type_info* bar;
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/151277
More information about the cfe-commits
mailing list