Author: Paul Kirth Date: 2024-12-18T08:39:19-08:00 New Revision: 2b932bc111c0d96db7044b0a854d7ad763710df2
URL: https://github.com/llvm/llvm-project/commit/2b932bc111c0d96db7044b0a854d7ad763710df2 DIFF: https://github.com/llvm/llvm-project/commit/2b932bc111c0d96db7044b0a854d7ad763710df2.diff LOG: [clang-doc] Use LangOpts when printing types (#120308) 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 Added: Modified: clang-tools-extra/clang-doc/Serialize.cpp clang-tools-extra/test/clang-doc/builtin_types.cpp clang-tools-extra/test/clang-doc/templates.cpp clang-tools-extra/unittests/clang-doc/SerializeTest.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp index b9db78cf7d688f..93efdd44f45898 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/builtin_types.cpp b/clang-tools-extra/test/clang-doc/builtin_types.cpp index 3972cb606c3c64..6c1fc8a1d7879b 100644 --- a/clang-tools-extra/test/clang-doc/builtin_types.cpp +++ b/clang-tools-extra/test/clang-doc/builtin_types.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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits