Skip to content

[clang-doc] Use LangOpts when printing types #120308

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

ilovepi
Copy link
Contributor

@ilovepi ilovepi commented Dec 17, 2024

The implementation in the clang-doc serializer failed to take in the
LangOpts from the declaration. As a result, we'd do things like print
_Bool instead of bool, even in C++ code.

Fixes #62970

Created using spr 1.3.6-beta.1

[skip ci]
Created using spr 1.3.6-beta.1
@llvmbot
Copy link
Member

llvmbot commented Dec 17, 2024

@llvm/pr-subscribers-clang-tools-extra

Author: Paul Kirth (ilovepi)

Changes

The implementation in the clang-doc serializer failed to take in the
LangOpts from the declaration. Asa result, we'd do things like print
_Bool instead of bool, even in C++ code.

Fixes #62970


Full diff: https://github.com/llvm/llvm-project/pull/120308.diff

4 Files Affected:

  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+13-8)
  • (modified) clang-tools-extra/test/clang-doc/basic.cpp (+3-3)
  • (modified) clang-tools-extra/test/clang-doc/templates.cpp (+6-6)
  • (modified) clang-tools-extra/unittests/clang-doc/SerializeTest.cpp (+4-2)
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index b9db78cf7d688f..ddac5399b966d4 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -236,10 +236,10 @@ static RecordDecl *getRecordDeclForType(const QualType &T) {
   return nullptr;
 }
 
-TypeInfo getTypeInfoForType(const QualType &T) {
+TypeInfo getTypeInfoForType(const QualType &T, const PrintingPolicy& Policy) {
   const TagDecl *TD = getTagDeclForType(T);
   if (!TD)
-    return TypeInfo(Reference(SymbolID(), T.getAsString()));
+    return TypeInfo(Reference(SymbolID(), T.getAsString(Policy)));
 
   InfoType IT;
   if (dyn_cast<EnumDecl>(TD)) {
@@ -250,7 +250,7 @@ TypeInfo getTypeInfoForType(const QualType &T) {
     IT = InfoType::IT_default;
   }
   return TypeInfo(Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
-                            T.getAsString(), getInfoRelativePath(TD)));
+                            T.getAsString(Policy), getInfoRelativePath(TD)));
 }
 
 static bool isPublic(const clang::AccessSpecifier AS,
@@ -379,10 +379,11 @@ static void parseFields(RecordInfo &I, const RecordDecl *D, bool PublicOnly,
     if (!shouldSerializeInfo(PublicOnly, /*IsInAnonymousNamespace=*/false, F))
       continue;
 
+    auto &LO = F->getLangOpts();
     // Use getAccessUnsafe so that we just get the default AS_none if it's not
     // valid, as opposed to an assert.
     MemberTypeInfo &NewMember = I.Members.emplace_back(
-        getTypeInfoForType(F->getTypeSourceInfo()->getType()),
+        getTypeInfoForType(F->getTypeSourceInfo()->getType(), LO),
         F->getNameAsString(),
         getFinalAccessSpecifier(Access, F->getAccessUnsafe()));
     populateMemberTypeInfo(NewMember, F);
@@ -412,9 +413,10 @@ static void parseEnumerators(EnumInfo &I, const EnumDecl *D) {
 }
 
 static void parseParameters(FunctionInfo &I, const FunctionDecl *D) {
+    auto &LO = D->getLangOpts();
   for (const ParmVarDecl *P : D->parameters()) {
     FieldTypeInfo &FieldInfo = I.Params.emplace_back(
-        getTypeInfoForType(P->getOriginalType()), P->getNameAsString());
+        getTypeInfoForType(P->getOriginalType(), LO), P->getNameAsString());
     FieldInfo.DefaultValue = getSourceCode(D, P->getDefaultArgRange());
   }
 }
@@ -541,7 +543,8 @@ static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
                                  bool &IsInAnonymousNamespace) {
   populateSymbolInfo(I, D, FC, LineNumber, Filename, IsFileInRootDir,
                      IsInAnonymousNamespace);
-  I.ReturnType = getTypeInfoForType(D->getReturnType());
+    auto &LO = D->getLangOpts();
+  I.ReturnType = getTypeInfoForType(D->getReturnType(), LO);
   parseParameters(I, D);
 
   PopulateTemplateParameters(I.Template, D);
@@ -783,7 +786,8 @@ emitInfo(const TypedefDecl *D, const FullComment *FC, int LineNumber,
     return {};
 
   Info.DefLoc.emplace(LineNumber, File, IsFileInRootDir);
-  Info.Underlying = getTypeInfoForType(D->getUnderlyingType());
+  auto &LO = D->getLangOpts();
+  Info.Underlying = getTypeInfoForType(D->getUnderlyingType(), LO);
   if (Info.Underlying.Type.Name.empty()) {
     // Typedef for an unnamed type. This is like "typedef struct { } Foo;"
     // The record serializer explicitly checks for this syntax and constructs
@@ -809,7 +813,8 @@ emitInfo(const TypeAliasDecl *D, const FullComment *FC, int LineNumber,
     return {};
 
   Info.DefLoc.emplace(LineNumber, File, IsFileInRootDir);
-  Info.Underlying = getTypeInfoForType(D->getUnderlyingType());
+  auto &LO = D->getLangOpts();
+  Info.Underlying = getTypeInfoForType(D->getUnderlyingType(), LO);
   Info.IsUsing = true;
 
   // Info is wrapped in its parent scope so is returned in the second position.
diff --git a/clang-tools-extra/test/clang-doc/basic.cpp b/clang-tools-extra/test/clang-doc/basic.cpp
index 318a271a9af04e..539ce8190ebbed 100644
--- a/clang-tools-extra/test/clang-doc/basic.cpp
+++ b/clang-tools-extra/test/clang-doc/basic.cpp
@@ -23,11 +23,11 @@ extern bool b();
 // YAML-NEXT:         Filename:        '{{.*}}'
 // YAML-NEXT:     ReturnType:
 // YAML-NEXT:       Type:
-// YAML-NEXT:         Name:            '_Bool'
-// YAML-NEXT:         QualName:        '_Bool'
+// YAML-NEXT:         Name:            'bool'
+// YAML-NEXT:         QualName:        'bool'
 
 // MD: ### b
-// MD: *_Bool b()*
+// MD: *bool b()*
 
 char c();
 
diff --git a/clang-tools-extra/test/clang-doc/templates.cpp b/clang-tools-extra/test/clang-doc/templates.cpp
index 5229063f7ee236..cab5426b7cefc1 100644
--- a/clang-tools-extra/test/clang-doc/templates.cpp
+++ b/clang-tools-extra/test/clang-doc/templates.cpp
@@ -80,8 +80,8 @@ void function<bool, 0>(bool x) {}
 // YAML-NEXT:       Filename:        '{{.*}}'
 // YAML-NEXT:     Params:
 // YAML-NEXT:       - Type:
-// YAML-NEXT:           Name:            '_Bool'
-// YAML-NEXT:           QualName:        '_Bool'
+// YAML-NEXT:           Name:            'bool'
+// YAML-NEXT:           QualName:        'bool'
 // YAML-NEXT:         Name:            'x'
 // YAML-NEXT:     ReturnType:
 // YAML-NEXT:       Type:
@@ -95,7 +95,7 @@ void function<bool, 0>(bool x) {}
 // YAML-NEXT:           - Contents:        '0'
 
 // MD: ### function
-// MD: *void function(_Bool x)*
+// MD: *void function(bool x)*
 // MD: *Defined at {{.*}}templates.cpp#[[# @LINE - 26]]*
 
 /// A Tuple type
@@ -136,7 +136,7 @@ tuple<int,int,bool> func_with_tuple_param(tuple<int,int,bool> t){ return t;}
 // YAML-NEXT:      - Type:
 // YAML-NEXT:          Type:            Record
 // YAML-NEXT:          Name:            'tuple'
-// YAML-NEXT:          QualName:        'tuple<int, int, _Bool>'
+// YAML-NEXT:          QualName:        'tuple<int, int, bool>'
 // YAML-NEXT:          USR:             '{{([0-9A-F]{40})}}'
 // YAML-NEXT:          Path:            'GlobalNamespace'
 // YAML-NEXT:        Name:            't'
@@ -144,13 +144,13 @@ tuple<int,int,bool> func_with_tuple_param(tuple<int,int,bool> t){ return t;}
 // YAML-NEXT:      Type:
 // YAML-NEXT:        Type:            Record
 // YAML-NEXT:        Name:            'tuple'
-// YAML-NEXT:        QualName:        'tuple<int, int, _Bool>'
+// YAML-NEXT:        QualName:        'tuple<int, int, bool>'
 // YAML-NEXT:        USR:             '{{([0-9A-F]{40})}}'
 // YAML-NEXT:        Path:            'GlobalNamespace'
 // YAML-NEXT: ...
 
 // MD: ### func_with_tuple_param
-// MD: *tuple<int, int, _Bool> func_with_tuple_param(tuple<int, int, _Bool> t)*
+// MD: *tuple<int, int, bool> func_with_tuple_param(tuple<int, int, bool> t)*
 // MD: *Defined at {{.*}}templates.cpp#[[# @LINE - 44]]*
 // MD:  A function with a tuple parameter
 // MD: **t** The input to func_with_tuple_param
diff --git a/clang-tools-extra/unittests/clang-doc/SerializeTest.cpp b/clang-tools-extra/unittests/clang-doc/SerializeTest.cpp
index 5df42b9f5bca0b..e6168418b58fa2 100644
--- a/clang-tools-extra/unittests/clang-doc/SerializeTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/SerializeTest.cpp
@@ -631,8 +631,8 @@ TEST(SerializeTests, emitTypedefs) {
 TEST(SerializeTests, emitFunctionTemplate) {
   EmittedInfoList Infos;
   // A template and a specialization.
-  ExtractInfosFromCode("template<typename T = int> void GetFoo(T);\n"
-                       "template<> void GetFoo<bool>(bool);",
+  ExtractInfosFromCode("template<typename T = int> bool GetFoo(T);\n"
+                       "template<> bool GetFoo<bool>(bool);",
                        2,
                        /*Public=*/false, Infos);
 
@@ -666,6 +666,8 @@ TEST(SerializeTests, emitFunctionTemplate) {
   ASSERT_EQ(1u, Func2.Template->Specialization->Params.size());
   EXPECT_EQ("bool", Func2.Template->Specialization->Params[0].Contents);
   EXPECT_EQ(Func1.USR, Func2.Template->Specialization->SpecializationOf);
+
+  EXPECT_EQ("bool", Func2.ReturnType.Type.Name);
 }
 
 TEST(SerializeTests, emitClassTemplate) {

@ilovepi ilovepi requested a review from PeterChou1 December 17, 2024 22:00
@ilovepi ilovepi changed the base branch from users/ilovepi/spr/main.clang-doc-use-langopts-when-printing-types to main December 17, 2024 22:01
Copy link

github-actions bot commented Dec 17, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@ilovepi ilovepi requested a review from petrhosek December 17, 2024 22:01
@ilovepi
Copy link
Contributor Author

ilovepi commented Dec 17, 2024

CC: @NekkoDroid

Created using spr 1.3.6-beta.1

[skip ci]
Created using spr 1.3.6-beta.1
@ilovepi ilovepi changed the base branch from main to users/ilovepi/spr/main.clang-doc-use-langopts-when-printing-types-1 December 17, 2024 22:04
@ilovepi ilovepi changed the base branch from users/ilovepi/spr/main.clang-doc-use-langopts-when-printing-types-1 to main December 17, 2024 22:13
Created using spr 1.3.6-beta.1

[skip ci]
Created using spr 1.3.6-beta.1
@ilovepi ilovepi changed the base branch from main to users/ilovepi/spr/main.clang-doc-use-langopts-when-printing-types-2 December 17, 2024 22:15
Created using spr 1.3.6-beta.1

[skip ci]
Created using spr 1.3.6-beta.1
ilovepi added a commit that referenced this pull request Dec 17, 2024
This is a precommit test for #120308, since we lack non-template
functions that use builtin types.
@ilovepi ilovepi changed the base branch from users/ilovepi/spr/main.clang-doc-use-langopts-when-printing-types-2 to main December 17, 2024 23:57
Created using spr 1.3.6-beta.1
@ilovepi ilovepi merged commit 2b932bc into main Dec 18, 2024
8 checks passed
@ilovepi ilovepi deleted the users/ilovepi/spr/clang-doc-use-langopts-when-printing-types branch December 18, 2024 16:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[clang-doc] bool types in C++ sources get output as _Bool
3 participants