[clang] [clang][ExtractAPI][NFC] pass params by const reference (PR #94820)
daniel-grumberg wrote: Thanks for looking at these, I think it would be best to try and leverage move semantics where possible if we are going to change this code. https://github.com/llvm/llvm-project/pull/94820 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI][NFC] pass params by const reference (PR #94820)
@@ -240,7 +241,7 @@ class DeclarationFragments { class AccessControl { public: - AccessControl(std::string Access) : Access(Access) {} daniel-grumberg wrote: Again I would prefer if we kept the value semantic ones and use `std::move` https://github.com/llvm/llvm-project/pull/94820 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI][NFC] pass params by const reference (PR #94820)
@@ -199,7 +199,8 @@ class DeclarationFragments { return *this; } - DeclarationFragments (std::string NewSpelling, unsigned Position) { daniel-grumberg wrote: I would prefer to keep the value semantics version and instead move assign the value, that way callers can move the string in and avoid any copies. https://github.com/llvm/llvm-project/pull/94820 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Flatten all enum cases from anonymous enums at top level (PR #93559)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/93559 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Flatten all enum cases from anonymous enums at top level (PR #93559)
https://github.com/daniel-grumberg updated https://github.com/llvm/llvm-project/pull/93559 >From 5c8258fb2bcc102d431af9f3ae41cf72ecc335b6 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Tue, 28 May 2024 15:43:45 +0100 Subject: [PATCH] [clang][ExtractAPI] Flatten all enum cases from anonymous enums at top level rdar://128863241 --- .../clang/ExtractAPI/ExtractAPIVisitor.h | 65 +- .../ExtractAPI/anonymous_record_no_typedef.c | 42 ++- clang/test/ExtractAPI/enum.c | 112 -- clang/tools/libclang/CXExtractAPI.cpp | 3 + 4 files changed, 54 insertions(+), 168 deletions(-) diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index 8ccebe457ed53..76d7fd798bed3 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -21,6 +21,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ParentMapContext.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Specifiers.h" @@ -127,7 +128,7 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { protected: /// Collect API information for the enum constants and associate with the /// parent enum. - void recordEnumConstants(EnumRecord *EnumRecord, + void recordEnumConstants(SymbolReference Container, const EnumDecl::enumerator_range Constants); /// Collect API information for the Objective-C methods and associate with the @@ -248,12 +249,8 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { clang::index::generateUSRForDecl(Tag, TagUSR); if (auto *Record = llvm::dyn_cast_if_present( API.findRecordForUSR(TagUSR))) { - if (Record->IsEmbeddedInVarDeclarator) { + if (Record->IsEmbeddedInVarDeclarator) NewRecordContext->stealRecordChain(*Record); -auto *NewRecord = cast(NewRecordContext); -if (NewRecord->Comment.empty()) - NewRecord->Comment = Record->Comment; - } } } }; @@ -394,17 +391,6 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const EnumDecl *Decl) { if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) return true; - SmallString<128> QualifiedNameBuffer; - // Collect symbol information. - StringRef Name = Decl->getName(); - if (Name.empty()) -Name = getTypedefName(Decl); - if (Name.empty()) { -llvm::raw_svector_ostream OS(QualifiedNameBuffer); -Decl->printQualifiedName(OS); -Name = QualifiedNameBuffer; - } - SmallString<128> USR; index::generateUSRForDecl(Decl, USR); PresumedLoc Loc = @@ -420,13 +406,29 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const EnumDecl *Decl) { DeclarationFragmentsBuilder::getFragmentsForEnum(Decl); DeclarationFragments SubHeading = DeclarationFragmentsBuilder::getSubHeading(Decl); - auto *ER = API.createRecord( - USR, Name, createHierarchyInformationForDecl(*Decl), Loc, - AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, - isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl)); + + // Collect symbol information. + SymbolReference ParentContainer; + + if (Decl->hasNameForLinkage()) { +StringRef Name = Decl->getName(); +if (Name.empty()) + Name = getTypedefName(Decl); + +auto *ER = API.createRecord( +USR, Name, createHierarchyInformationForDecl(*Decl), Loc, +AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, +SubHeading, isInSystemHeader(Decl), false); +ParentContainer = SymbolReference(ER); + } else { +// If this an anonymous enum then the parent scope of the constants is the +// top level namespace. +ParentContainer = {}; + } // Now collect information about the enumerators in this enum. - getDerivedExtractAPIVisitor().recordEnumConstants(ER, Decl->enumerators()); + getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer, +Decl->enumerators()); return true; } @@ -1197,7 +1199,7 @@ bool ExtractAPIVisitorBase::VisitObjCCategoryDecl( /// parent enum. template void ExtractAPIVisitorBase::recordEnumConstants( -EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants) { +SymbolReference Container, const EnumDecl::enumerator_range Constants) { for (const auto *Constant : Constants) { // Collect symbol information. StringRef Name = Constant->getName(); @@ -1218,9 +1220,8 @@ void ExtractAPIVisitorBase::recordEnumConstants( DeclarationFragmentsBuilder::getSubHeading(Constant); API.createRecord( -USR, Name, createHierarchyInformationForDecl(*Constant), Loc, -AvailabilityInfo::createFromDecl(Constant), Comment, Declaration, -SubHeading,
[clang] [clang][ExtractAPI] Flatten all enum cases from anonymous enums at top level (PR #93559)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/93559 rdar://128863241 >From d453e5b21d369d8c2b1d06c640887ec81ace Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Tue, 28 May 2024 15:43:45 +0100 Subject: [PATCH] [clang][ExtractAPI] Flatten all enum cases from anonymous enums at top level rdar://128863241 --- .../clang/ExtractAPI/ExtractAPIVisitor.h | 57 + .../ExtractAPI/anonymous_record_no_typedef.c | 42 ++- clang/test/ExtractAPI/enum.c | 112 -- clang/tools/libclang/CXExtractAPI.cpp | 3 + 4 files changed, 50 insertions(+), 164 deletions(-) diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index 8ccebe457ed53..9df5138a223da 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -21,6 +21,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ParentMapContext.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Specifiers.h" @@ -127,7 +128,7 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { protected: /// Collect API information for the enum constants and associate with the /// parent enum. - void recordEnumConstants(EnumRecord *EnumRecord, + void recordEnumConstants(SymbolReference Container, const EnumDecl::enumerator_range Constants); /// Collect API information for the Objective-C methods and associate with the @@ -248,12 +249,8 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { clang::index::generateUSRForDecl(Tag, TagUSR); if (auto *Record = llvm::dyn_cast_if_present( API.findRecordForUSR(TagUSR))) { - if (Record->IsEmbeddedInVarDeclarator) { + if (Record->IsEmbeddedInVarDeclarator) NewRecordContext->stealRecordChain(*Record); -auto *NewRecord = cast(NewRecordContext); -if (NewRecord->Comment.empty()) - NewRecord->Comment = Record->Comment; - } } } }; @@ -394,17 +391,6 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const EnumDecl *Decl) { if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) return true; - SmallString<128> QualifiedNameBuffer; - // Collect symbol information. - StringRef Name = Decl->getName(); - if (Name.empty()) -Name = getTypedefName(Decl); - if (Name.empty()) { -llvm::raw_svector_ostream OS(QualifiedNameBuffer); -Decl->printQualifiedName(OS); -Name = QualifiedNameBuffer; - } - SmallString<128> USR; index::generateUSRForDecl(Decl, USR); PresumedLoc Loc = @@ -420,13 +406,27 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const EnumDecl *Decl) { DeclarationFragmentsBuilder::getFragmentsForEnum(Decl); DeclarationFragments SubHeading = DeclarationFragmentsBuilder::getSubHeading(Decl); - auto *ER = API.createRecord( + + // Collect symbol information. + SymbolReference ParentContainer; + + if (Decl->hasNameForLinkage()) { +StringRef Name = Decl->getName(); +if (Name.empty()) + Name = getTypedefName(Decl); + +auto *ER = API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, - isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl)); + isInSystemHeader(Decl), false); +ParentContainer = SymbolReference(ER); + } else { +// If this an anonymous enum then the parent scope of the constants is the top level namespace. +ParentContainer = {}; + } // Now collect information about the enumerators in this enum. - getDerivedExtractAPIVisitor().recordEnumConstants(ER, Decl->enumerators()); + getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer, Decl->enumerators()); return true; } @@ -1197,7 +1197,7 @@ bool ExtractAPIVisitorBase::VisitObjCCategoryDecl( /// parent enum. template void ExtractAPIVisitorBase::recordEnumConstants( -EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants) { +SymbolReference Container, const EnumDecl::enumerator_range Constants) { for (const auto *Constant : Constants) { // Collect symbol information. StringRef Name = Constant->getName(); @@ -1218,7 +1218,7 @@ void ExtractAPIVisitorBase::recordEnumConstants( DeclarationFragmentsBuilder::getSubHeading(Constant); API.createRecord( -USR, Name, createHierarchyInformationForDecl(*Constant), Loc, +USR, Name, Container, Loc, AvailabilityInfo::createFromDecl(Constant), Comment, Declaration, SubHeading, isInSystemHeader(Constant)); } @@ -1469,7 +1469,18 @@ class ExtractAPIVisitor bool shouldDeclBeIncluded(const Decl *D) const { return true; } const RawComment
[clang] [clang][ExtractAPI] Ensure TemplateArgumentLocations are only accessed if available (PR #93205)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/93205 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Ensure TemplateArgumentLocations are only accessed if available (PR #93205)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/93205 None >From d4e7e838fcbdf1645e5e31cefb462d53e59361d4 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Thu, 23 May 2024 15:24:53 +0100 Subject: [PATCH] [clang][ExtractAPI] Ensure TemplateArgumentLocations are only accessed if available --- clang/lib/ExtractAPI/DeclarationFragments.cpp | 32 +- clang/test/ExtractAPI/non_type_template.cpp | 44 +++ 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 904b9315f26ef..8c7c0f8a14726 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -1084,12 +1084,22 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateArguments( if (StringRef(ArgumentFragment.begin()->Spelling) .starts_with("type-parameter")) { -std::string ProperArgName = TemplateArgumentLocs.value()[i] -.getTypeSourceInfo() -->getType() -.getAsString(); -ArgumentFragment.begin()->Spelling.swap(ProperArgName); +if (TemplateArgumentLocs.has_value() && +TemplateArgumentLocs->size() > i) { + std::string ProperArgName = TemplateArgumentLocs.value()[i] + .getTypeSourceInfo() + ->getType() + .getAsString(); + ArgumentFragment.begin()->Spelling.swap(ProperArgName); +} else { + auto = ArgumentFragment.begin()->Spelling; + Spelling.clear(); + raw_string_ostream OutStream(Spelling); + CTA.print(Context.getPrintingPolicy(), OutStream, false); + OutStream.flush(); +} } + Fragments.append(std::move(ArgumentFragment)); break; } @@ -1212,9 +1222,9 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization( cast(Decl))) .pop_back() // there is an extra semicolon now .append("<", DeclarationFragments::FragmentKind::Text) - .append( - getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(), - Decl->getASTContext(), std::nullopt)) + .append(getFragmentsForTemplateArguments( + Decl->getTemplateArgs().asArray(), Decl->getASTContext(), + Decl->getTemplateArgsAsWritten()->arguments())) .append(">", DeclarationFragments::FragmentKind::Text) .appendSemicolon(); } @@ -1255,9 +1265,9 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization( .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl)) .pop_back() // there is an extra semicolon now .append("<", DeclarationFragments::FragmentKind::Text) - .append( - getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(), - Decl->getASTContext(), std::nullopt)) + .append(getFragmentsForTemplateArguments( + Decl->getTemplateArgs().asArray(), Decl->getASTContext(), + Decl->getTemplateArgsAsWritten()->arguments())) .append(">", DeclarationFragments::FragmentKind::Text) .appendSemicolon(); } diff --git a/clang/test/ExtractAPI/non_type_template.cpp b/clang/test/ExtractAPI/non_type_template.cpp index 4e65eb790ca11..85f38e39c82bc 100644 --- a/clang/test/ExtractAPI/non_type_template.cpp +++ b/clang/test/ExtractAPI/non_type_template.cpp @@ -310,4 +310,48 @@ NestedTemplateTemplateParamPack var; // VAR-NEXT: } // VAR-NEXT: ] +template +class TypeContainer { + public: +// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix TYPE +typedef Foo Type; +// TYPE-LABEL: "!testLabel": "c:non_type_template.cpp@ST>1#T@TypeContainer@T@Type", +// TYPE: "declarationFragments": [ +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "keyword", +// TYPE-NEXT: "spelling": "typedef" +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "text", +// TYPE-NEXT: "spelling": " " +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "typeIdentifier", +// TYPE-NEXT: "preciseIdentifier": "c:@ST>2#T#NI@Foo", +// TYPE-NEXT: "spelling": "Foo" +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "text", +// TYPE-NEXT: "spelling": "<" +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "typeIdentifier", +// TYPE-NEXT: "preciseIdentifier": "c:t0.0", +// TYPE-NEXT: "spelling": "T" +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "text", +// TYPE-NEXT: "spelling": "> " +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "identifier", +// TYPE-NEXT: "spelling": "Type" +// TYPE-NEXT:
[clang] [clang][ExtractAPI] Remove symbols defined in categories to external types unless requested (PR #92522)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/92522 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Remove symbols defined in categories to external types unless requested (PR #92522)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/92522 rdar://128259890 >From 7650c18c883bb14e5a4b17d6b6d61297f2fa3c44 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Fri, 17 May 2024 11:58:18 +0100 Subject: [PATCH] [clang][ExtractAPI] Remove symbols defined in categories to external types unless requested rdar://128259890 --- .../Serialization/SymbolGraphSerializer.h | 9 +++-- .../Serialization/SymbolGraphSerializer.cpp| 11 +-- clang/test/ExtractAPI/objc_external_category.m | 18 +- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h index 724b087f7aea9..27e9167ca1ad0 100644 --- a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h +++ b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h @@ -102,6 +102,8 @@ class SymbolGraphSerializer : public APISetVisitor { const bool EmitSymbolLabelsForTesting = false; + const bool SkipSymbolsInCategoriesToExternalTypes = false; + /// The object instantiated by the last call to serializeAPIRecord. Object *CurrentSymbol = nullptr; @@ -271,10 +273,13 @@ class SymbolGraphSerializer : public APISetVisitor { SymbolGraphSerializer(const APISet , const APIIgnoresList , bool EmitSymbolLabelsForTesting = false, -bool ForceEmitToMainModule = false) +bool ForceEmitToMainModule = false, +bool SkipSymbolsInCategoriesToExternalTypes = false) : Base(API), ForceEmitToMainModule(ForceEmitToMainModule), IgnoresList(IgnoresList), -EmitSymbolLabelsForTesting(EmitSymbolLabelsForTesting) {} +EmitSymbolLabelsForTesting(EmitSymbolLabelsForTesting), +SkipSymbolsInCategoriesToExternalTypes( +SkipSymbolsInCategoriesToExternalTypes) {} }; } // namespace extractapi diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index c16d4623f115d..08e711cafae28 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -925,6 +925,10 @@ bool SymbolGraphSerializer::visitObjCInterfaceRecord( bool SymbolGraphSerializer::traverseObjCCategoryRecord( const ObjCCategoryRecord *Record) { + if (SkipSymbolsInCategoriesToExternalTypes && + !API.findRecordForUSR(Record->Interface.USR)) +return true; + auto *CurrentModule = ModuleForCurrentSymbol; if (Record->isExtendingExternalModule()) ModuleForCurrentSymbol = [Record->Interface.Source]; @@ -1040,8 +1044,11 @@ void SymbolGraphSerializer::serializeGraphToStream( void SymbolGraphSerializer::serializeMainSymbolGraph( raw_ostream , const APISet , const APIIgnoresList , SymbolGraphSerializerOption Options) { - SymbolGraphSerializer Serializer(API, IgnoresList, - Options.EmitSymbolLabelsForTesting); + SymbolGraphSerializer Serializer( + API, IgnoresList, Options.EmitSymbolLabelsForTesting, + /*ForceEmitToMainModule=*/true, + /*SkipSymbolsInCategoriesToExternalTypes=*/true); + Serializer.traverseAPISet(); Serializer.serializeGraphToStream(OS, Options, API.ProductName, std::move(Serializer.MainModule)); diff --git a/clang/test/ExtractAPI/objc_external_category.m b/clang/test/ExtractAPI/objc_external_category.m index 47e699cb91c0e..8afc92489f28b 100644 --- a/clang/test/ExtractAPI/objc_external_category.m +++ b/clang/test/ExtractAPI/objc_external_category.m @@ -4,6 +4,9 @@ // RUN: --emit-extension-symbol-graphs --symbol-graph-dir=%t/symbols \ // RUN: --product-name=Module -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules-cache \ // RUN: -triple arm64-apple-macosx -x objective-c-header %t/input.h -verify +// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \ +// RUN: --product-name=Module -o %t/ModuleNoExt.symbols.json -triple arm64-apple-macosx \ +// RUN: -x objective-c-header %t/input.h //--- input.h #include "ExternalModule.h" @@ -28,15 +31,20 @@ @interface ExtInterface header "ExternalModule.h" } +// Main symbol graph from the build with extension SGFs // RUN: FileCheck %s --input-file %t/symbols/Module.symbols.json --check-prefix MOD + // MOD-NOT: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(py)Property $ c:objc(cs)ExtInterface" // MOD-NOT: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(im)InstanceMethod $ c:objc(cs)ExtInterface" // MOD-NOT: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(cm)ClassMethod $ c:objc(cs)ExtInterface" -// MOD-NOT: "!testLabel": "c:objc(cs)ExtInterface(py)Property" -// MOD-NOT: "!testLabel":
[clang] [clang][ExtractAPI] Correctly generate declaration fragments for non-type template parameters (PR #91958)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/91958 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ExtractAPI,test] fix filecheck annotation (PR #92231)
https://github.com/daniel-grumberg approved this pull request. LGTM! Thanks for doing this! https://github.com/llvm/llvm-project/pull/92231 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Correctly generate declaration fragments for non-type template parameters (PR #91958)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/91958 Previously we only generated declaration fragments for template type parameters/arguments, this adds supports for most other possible template parameters/arguments. rdar://127732598 >From d86e4256da57451a08d580b8eecd5525bd1642c6 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Wed, 8 May 2024 12:22:47 +0100 Subject: [PATCH] [clang][ExtractAPI] Correctly generate declaration fragments for non-type template parameters. Previously we only generated declaration fragments for template type paramters/arguments, this adds supports for most other possible template parameters/arguments. rdar://127732598 --- clang/lib/ExtractAPI/DeclarationFragments.cpp | 226 ++--- clang/test/ExtractAPI/class_template.cpp | 2 +- .../class_template_param_inheritance.cpp | 2 +- .../class_template_partial_spec.cpp | 4 +- clang/test/ExtractAPI/class_template_spec.cpp | 4 +- clang/test/ExtractAPI/concept.cpp | 2 +- clang/test/ExtractAPI/field_template.cpp | 2 +- .../test/ExtractAPI/global_func_template.cpp | 4 +- .../ExtractAPI/global_func_template_spec.cpp | 4 +- clang/test/ExtractAPI/global_var_template.cpp | 2 +- .../global_var_template_partial_spec.cpp | 4 +- .../ExtractAPI/global_var_template_spec.cpp | 4 +- clang/test/ExtractAPI/method_template.cpp | 2 +- .../test/ExtractAPI/method_template_spec.cpp | 4 +- clang/test/ExtractAPI/non_type_template.cpp | 313 ++ 15 files changed, 522 insertions(+), 57 deletions(-) create mode 100644 clang/test/ExtractAPI/non_type_template.cpp diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 9bf7950888dbb..98b9343924a83 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -12,13 +12,19 @@ //===--===// #include "clang/ExtractAPI/DeclarationFragments.h" +#include "clang/AST/ASTFwd.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" #include "clang/Index/USRGeneration.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include using namespace clang::extractapi; using namespace llvm; @@ -386,6 +392,25 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( getFragmentsForType(AT->getElementType(), Context, After)); } + if (const TemplateSpecializationType *TemplSpecTy = + dyn_cast(T)) { +const auto TemplName = TemplSpecTy->getTemplateName(); +std::string Str; +raw_string_ostream Stream(Str); +TemplName.print(Stream, Context.getPrintingPolicy(), +TemplateName::Qualified::AsWritten); +SmallString<64> USR(""); +if (const auto *TemplDecl = TemplName.getAsTemplateDecl()) + index::generateUSRForDecl(TemplDecl, USR); + +return Fragments +.append(Str, DeclarationFragments::FragmentKind::TypeIdentifier, USR) +.append("<", DeclarationFragments::FragmentKind::Text) +.append(getFragmentsForTemplateArguments( +TemplSpecTy->template_arguments(), Context, std::nullopt)) +.append(">", DeclarationFragments::FragmentKind::Text); + } + // Everything we care about has been handled now, reduce to the canonical // unqualified base type. QualType Base = T->getCanonicalTypeUnqualified(); @@ -650,7 +675,6 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForBlock( DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) { DeclarationFragments Fragments; - // FIXME: Handle template specialization switch (Func->getStorageClass()) { case SC_None: case SC_PrivateExtern: @@ -952,27 +976,84 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateParameters( Fragments.append(",", DeclarationFragments::FragmentKind::Text) .appendSpace(); -const auto *TemplateParam = -dyn_cast(ParameterArray[i]); -if (!TemplateParam) - continue; -if (TemplateParam->hasTypeConstraint()) - Fragments.append(TemplateParam->getTypeConstraint() - ->getNamedConcept() - ->getName() - .str(), - DeclarationFragments::FragmentKind::TypeIdentifier); -else if (TemplateParam->wasDeclaredWithTypename()) - Fragments.append("typename", DeclarationFragments::FragmentKind::Keyword); -else - Fragments.append("class", DeclarationFragments::FragmentKind::Keyword); - -if
[clang] [clang][ExtractAPI] Distinguish between record kind for display and for RTTI (PR #91466)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/91466 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [flang] [llvm] [mlir] [polly] [test]: fix filecheck annotation typos (PR #91854)
https://github.com/daniel-grumberg approved this pull request. LGTM to me for the ExtractAPI one. https://github.com/llvm/llvm-project/pull/91854 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Distinguish between record kind for display and for RTTI (PR #91466)
https://github.com/daniel-grumberg updated https://github.com/llvm/llvm-project/pull/91466 >From a8c7763ed5f36e4faeba5eece2827b2dec010734 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Wed, 8 May 2024 11:55:15 +0100 Subject: [PATCH] [clang][ExtractAPI] Distinguish between record kind for display and for RTTI rdar://127732562 --- clang/include/clang/ExtractAPI/API.h | 7 -- .../clang/ExtractAPI/ExtractAPIVisitor.h | 25 +++ .../Serialization/SymbolGraphSerializer.cpp | 6 ++--- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index d323e1668a72..bf291074fd06 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -266,6 +266,8 @@ struct APIRecord { AccessControl Access; + RecordKind KindForDisplay; + private: const RecordKind Kind; friend class RecordContext; @@ -277,6 +279,7 @@ struct APIRecord { APIRecord *getNextInContext() const { return NextInContext; } RecordKind getKind() const { return Kind; } + RecordKind getKindForDisplay() const { return KindForDisplay; } static APIRecord *castFromRecordContext(const RecordContext *Ctx); static RecordContext *castToRecordContext(const APIRecord *Record); @@ -293,10 +296,10 @@ struct APIRecord { Availability(std::move(Availability)), Linkage(Linkage), Comment(Comment), Declaration(Declaration), SubHeading(SubHeading), IsFromSystemHeader(IsFromSystemHeader), Access(std::move(Access)), -Kind(Kind) {} +KindForDisplay(Kind), Kind(Kind) {} APIRecord(RecordKind Kind, StringRef USR, StringRef Name) - : USR(USR), Name(Name), Kind(Kind) {} + : USR(USR), Name(Name), KindForDisplay(Kind), Kind(Kind) {} // Pure virtual destructor to make APIRecord abstract virtual ~APIRecord() = 0; diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index 97cc457ea2a9..8ccebe457ed5 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -194,6 +194,15 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { return Bases; } + APIRecord::RecordKind getKindForDisplay(const CXXRecordDecl *Decl) { +if (Decl->isUnion()) + return APIRecord::RK_Union; +if (Decl->isStruct()) + return APIRecord::RK_Struct; + +return APIRecord::RK_CXXClass; + } + StringRef getOwningModuleName(const Decl ) { if (auto *OwningModule = D.getImportedOwningModule()) return OwningModule->Name; @@ -599,13 +608,6 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl( DeclarationFragments SubHeading = DeclarationFragmentsBuilder::getSubHeading(Decl); - APIRecord::RecordKind Kind; - if (Decl->isUnion()) -Kind = APIRecord::RecordKind::RK_Union; - else if (Decl->isStruct()) -Kind = APIRecord::RecordKind::RK_Struct; - else -Kind = APIRecord::RecordKind::RK_CXXClass; auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl); CXXClassRecord *Record; @@ -619,13 +621,15 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl( AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, Template(Decl->getDescribedClassTemplate()), Access, isInSystemHeader(Decl)); - } else + } else { Record = API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, -SubHeading, Kind, Access, isInSystemHeader(Decl), -isEmbeddedInVarDeclarator(*Decl)); +SubHeading, APIRecord::RecordKind::RK_CXXClass, Access, +isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl)); + } + Record->KindForDisplay = getKindForDisplay(Decl); Record->Bases = getBases(Decl); return true; @@ -849,6 +853,7 @@ bool ExtractAPIVisitorBase:: Template(Decl), DeclarationFragmentsBuilder::getAccessControl(Decl), isInSystemHeader(Decl)); + CTPSR->KindForDisplay = getKindForDisplay(Decl); CTPSR->Bases = getBases(Decl); return true; diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 34278b5d40c4..c16d4623f115 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -514,7 +514,7 @@ Object serializeSymbolKind(APIRecord::RecordKind RK, Language Lang) { /// which is prefixed by the source language name, useful for tooling to parse /// the kind, and a \c displayName for rendering human-readable names. Object serializeSymbolKind(const APIRecord , Language Lang) { - return serializeSymbolKind(Record.getKind(), Lang); + return serializeSymbolKind(Record.KindForDisplay, Lang); } /// Serialize the function
[clang] [clang][ExtractAPI] Distinguish between record kind for display and for RTTI (PR #91466)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/91466 rdar://127732562 >From d1118a8552d84e044cd0f22cd8b46e5e65b43cae Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Wed, 8 May 2024 11:55:15 +0100 Subject: [PATCH] [clang][ExtractAPI] Distinguish between record kind for display and for RTTI --- clang/include/clang/ExtractAPI/API.h | 6 +++-- .../clang/ExtractAPI/ExtractAPIVisitor.h | 23 +++ .../Serialization/SymbolGraphSerializer.cpp | 4 ++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index d323e1668a72b..d2341f004c52f 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -266,6 +266,7 @@ struct APIRecord { AccessControl Access; + RecordKind KindForDisplay; private: const RecordKind Kind; friend class RecordContext; @@ -277,6 +278,7 @@ struct APIRecord { APIRecord *getNextInContext() const { return NextInContext; } RecordKind getKind() const { return Kind; } + RecordKind getKindForDisplay() const { return KindForDisplay; } static APIRecord *castFromRecordContext(const RecordContext *Ctx); static RecordContext *castToRecordContext(const APIRecord *Record); @@ -293,10 +295,10 @@ struct APIRecord { Availability(std::move(Availability)), Linkage(Linkage), Comment(Comment), Declaration(Declaration), SubHeading(SubHeading), IsFromSystemHeader(IsFromSystemHeader), Access(std::move(Access)), -Kind(Kind) {} +KindForDisplay(Kind), Kind(Kind) {} APIRecord(RecordKind Kind, StringRef USR, StringRef Name) - : USR(USR), Name(Name), Kind(Kind) {} + : USR(USR), Name(Name), KindForDisplay(Kind), Kind(Kind) {} // Pure virtual destructor to make APIRecord abstract virtual ~APIRecord() = 0; diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index 97cc457ea2a92..482a81f750a76 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -194,6 +194,15 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { return Bases; } + APIRecord::RecordKind getKindForDisplay(const CXXRecordDecl *Decl) { +if (Decl->isUnion()) + return APIRecord::RK_Union; +if (Decl->isStruct()) + return APIRecord::RK_Struct; + +return APIRecord::RK_CXXClass; + } + StringRef getOwningModuleName(const Decl ) { if (auto *OwningModule = D.getImportedOwningModule()) return OwningModule->Name; @@ -599,13 +608,6 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl( DeclarationFragments SubHeading = DeclarationFragmentsBuilder::getSubHeading(Decl); - APIRecord::RecordKind Kind; - if (Decl->isUnion()) -Kind = APIRecord::RecordKind::RK_Union; - else if (Decl->isStruct()) -Kind = APIRecord::RecordKind::RK_Struct; - else -Kind = APIRecord::RecordKind::RK_CXXClass; auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl); CXXClassRecord *Record; @@ -619,13 +621,15 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl( AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, Template(Decl->getDescribedClassTemplate()), Access, isInSystemHeader(Decl)); - } else + } else { Record = API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, -SubHeading, Kind, Access, isInSystemHeader(Decl), +SubHeading, APIRecord::RecordKind::RK_CXXClass, Access, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl)); + } + Record->KindForDisplay = getKindForDisplay(Decl); Record->Bases = getBases(Decl); return true; @@ -849,6 +853,7 @@ bool ExtractAPIVisitorBase:: Template(Decl), DeclarationFragmentsBuilder::getAccessControl(Decl), isInSystemHeader(Decl)); + CTPSR->KindForDisplay = getKindForDisplay(Decl); CTPSR->Bases = getBases(Decl); return true; diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 34278b5d40c42..952deccded07d 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -514,7 +514,7 @@ Object serializeSymbolKind(APIRecord::RecordKind RK, Language Lang) { /// which is prefixed by the source language name, useful for tooling to parse /// the kind, and a \c displayName for rendering human-readable names. Object serializeSymbolKind(const APIRecord , Language Lang) { - return serializeSymbolKind(Record.getKind(), Lang); + return serializeSymbolKind(Record.KindForDisplay, Lang); } /// Serialize the function signature field, as specified by the @@
[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/87772 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)
@@ -54,6 +54,20 @@ RecordContext *APIRecord::castToRecordContext(const APIRecord *Record) { } } +void RecordContext::stealRecordChain(RecordContext ) { + // If we don't have an empty chain append Other's chain into ours. + if (First) +Last->NextInContext = Other.First; daniel-grumberg wrote: Documented the invariant that `First` being non-null implies that `Last` is also non-null in an assert above. https://github.com/llvm/llvm-project/pull/87772 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)
https://github.com/daniel-grumberg updated https://github.com/llvm/llvm-project/pull/87772 >From 18912352db31406c7c5b530d6e22f77e775fbf38 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Thu, 4 Apr 2024 18:33:25 +0100 Subject: [PATCH 1/3] [clang][ExtractAPI] Fix handling of anonymous TagDecls This changes the handling of anonymous TagDecls to the following rules: - If the TagDecl is embedded in the declaration for some VarDecl (this is the only possibility for RecordDecls), then pretend the child decls belong to the VarDecl - If it's an EnumDecl proceed as we did previously, i.e., embed it in the enclosing DeclContext. Additionally this fixes a few issues with declaration fragments not consistently including "{ ... }" for anonymous TagDecls. To make testing these additions easier this patch fixes some text declaration fragments merging issues and updates tests accordingly. --- clang/include/clang/ExtractAPI/API.h | 132 ++-- clang/include/clang/ExtractAPI/APIRecords.inc | 16 +- .../clang/ExtractAPI/DeclarationFragments.h | 84 ++- .../clang/ExtractAPI/ExtractAPIVisitor.h | 76 ++- clang/lib/ExtractAPI/API.cpp | 8 + clang/lib/ExtractAPI/DeclarationFragments.cpp | 17 +- .../Serialization/SymbolGraphSerializer.cpp | 8 + .../ExtractAPI/anonymous_record_no_typedef.c | 565 +- clang/test/ExtractAPI/enum.c | 12 +- clang/test/ExtractAPI/function_noexcepts.cpp | 18 +- clang/test/ExtractAPI/methods.cpp | 6 +- clang/test/ExtractAPI/objc_block.m| 48 +- .../ExtractAPI/typedef_anonymous_record.c | 4 +- clang/test/ExtractAPI/typedef_struct_enum.c | 2 +- 14 files changed, 427 insertions(+), 569 deletions(-) diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index 92cacf65c7d64e..05cfabd072a560 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -208,20 +208,20 @@ struct APIRecord { RK_ClassTemplate, RK_ClassTemplateSpecialization, RK_ClassTemplatePartialSpecialization, -RK_LastRecordContext, -RK_GlobalFunction, -RK_GlobalFunctionTemplate, -RK_GlobalFunctionTemplateSpecialization, +RK_StructField, +RK_UnionField, +RK_CXXField, +RK_StaticField, +RK_CXXFieldTemplate, RK_GlobalVariable, RK_GlobalVariableTemplate, RK_GlobalVariableTemplateSpecialization, RK_GlobalVariableTemplatePartialSpecialization, +RK_LastRecordContext, +RK_GlobalFunction, +RK_GlobalFunctionTemplate, +RK_GlobalFunctionTemplateSpecialization, RK_EnumConstant, -RK_StructField, -RK_UnionField, -RK_StaticField, -RK_CXXField, -RK_CXXFieldTemplate, RK_Concept, RK_CXXStaticMethod, RK_CXXInstanceMethod, @@ -321,6 +321,8 @@ class RecordContext { RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {} + void stealRecordChain(RecordContext ); + APIRecord::RecordKind getKind() const { return Kind; } struct record_iterator { @@ -475,7 +477,7 @@ struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord { }; /// This holds information associated with global functions. -struct GlobalVariableRecord : APIRecord { +struct GlobalVariableRecord : APIRecord, RecordContext { GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, LinkageInfo Linkage, const DocComment , @@ -483,23 +485,28 @@ struct GlobalVariableRecord : APIRecord { DeclarationFragments SubHeading, bool IsFromSystemHeader) : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc, std::move(Availability), Linkage, Comment, Declaration, - SubHeading, IsFromSystemHeader) {} + SubHeading, IsFromSystemHeader), +RecordContext(RK_GlobalVariable) {} GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name, - SymbolReference Parent, - - PresumedLoc Loc, AvailabilityInfo Availability, - LinkageInfo Linkage, const DocComment , + SymbolReference Parent, PresumedLoc Loc, + AvailabilityInfo Availability, LinkageInfo Linkage, + const DocComment , DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader) : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability), Linkage, Comment, Declaration, SubHeading, - IsFromSystemHeader) {} + IsFromSystemHeader), +RecordContext(Kind) {} static bool classof(const APIRecord *Record) { return classofKind(Record->getKind()); } - static bool classofKind(RecordKind K) { return K ==
[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)
https://github.com/daniel-grumberg updated https://github.com/llvm/llvm-project/pull/87772 >From 18912352db31406c7c5b530d6e22f77e775fbf38 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Thu, 4 Apr 2024 18:33:25 +0100 Subject: [PATCH 1/2] [clang][ExtractAPI] Fix handling of anonymous TagDecls This changes the handling of anonymous TagDecls to the following rules: - If the TagDecl is embedded in the declaration for some VarDecl (this is the only possibility for RecordDecls), then pretend the child decls belong to the VarDecl - If it's an EnumDecl proceed as we did previously, i.e., embed it in the enclosing DeclContext. Additionally this fixes a few issues with declaration fragments not consistently including "{ ... }" for anonymous TagDecls. To make testing these additions easier this patch fixes some text declaration fragments merging issues and updates tests accordingly. --- clang/include/clang/ExtractAPI/API.h | 132 ++-- clang/include/clang/ExtractAPI/APIRecords.inc | 16 +- .../clang/ExtractAPI/DeclarationFragments.h | 84 ++- .../clang/ExtractAPI/ExtractAPIVisitor.h | 76 ++- clang/lib/ExtractAPI/API.cpp | 8 + clang/lib/ExtractAPI/DeclarationFragments.cpp | 17 +- .../Serialization/SymbolGraphSerializer.cpp | 8 + .../ExtractAPI/anonymous_record_no_typedef.c | 565 +- clang/test/ExtractAPI/enum.c | 12 +- clang/test/ExtractAPI/function_noexcepts.cpp | 18 +- clang/test/ExtractAPI/methods.cpp | 6 +- clang/test/ExtractAPI/objc_block.m| 48 +- .../ExtractAPI/typedef_anonymous_record.c | 4 +- clang/test/ExtractAPI/typedef_struct_enum.c | 2 +- 14 files changed, 427 insertions(+), 569 deletions(-) diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index 92cacf65c7d64e..05cfabd072a560 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -208,20 +208,20 @@ struct APIRecord { RK_ClassTemplate, RK_ClassTemplateSpecialization, RK_ClassTemplatePartialSpecialization, -RK_LastRecordContext, -RK_GlobalFunction, -RK_GlobalFunctionTemplate, -RK_GlobalFunctionTemplateSpecialization, +RK_StructField, +RK_UnionField, +RK_CXXField, +RK_StaticField, +RK_CXXFieldTemplate, RK_GlobalVariable, RK_GlobalVariableTemplate, RK_GlobalVariableTemplateSpecialization, RK_GlobalVariableTemplatePartialSpecialization, +RK_LastRecordContext, +RK_GlobalFunction, +RK_GlobalFunctionTemplate, +RK_GlobalFunctionTemplateSpecialization, RK_EnumConstant, -RK_StructField, -RK_UnionField, -RK_StaticField, -RK_CXXField, -RK_CXXFieldTemplate, RK_Concept, RK_CXXStaticMethod, RK_CXXInstanceMethod, @@ -321,6 +321,8 @@ class RecordContext { RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {} + void stealRecordChain(RecordContext ); + APIRecord::RecordKind getKind() const { return Kind; } struct record_iterator { @@ -475,7 +477,7 @@ struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord { }; /// This holds information associated with global functions. -struct GlobalVariableRecord : APIRecord { +struct GlobalVariableRecord : APIRecord, RecordContext { GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, LinkageInfo Linkage, const DocComment , @@ -483,23 +485,28 @@ struct GlobalVariableRecord : APIRecord { DeclarationFragments SubHeading, bool IsFromSystemHeader) : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc, std::move(Availability), Linkage, Comment, Declaration, - SubHeading, IsFromSystemHeader) {} + SubHeading, IsFromSystemHeader), +RecordContext(RK_GlobalVariable) {} GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name, - SymbolReference Parent, - - PresumedLoc Loc, AvailabilityInfo Availability, - LinkageInfo Linkage, const DocComment , + SymbolReference Parent, PresumedLoc Loc, + AvailabilityInfo Availability, LinkageInfo Linkage, + const DocComment , DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader) : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability), Linkage, Comment, Declaration, SubHeading, - IsFromSystemHeader) {} + IsFromSystemHeader), +RecordContext(Kind) {} static bool classof(const APIRecord *Record) { return classofKind(Record->getKind()); } - static bool classofKind(RecordKind K) { return K ==
[clang] [clang][ExtractAPI] Serialize platform specific unavailable attribute in symbol graphs (PR #89277)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/89277 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)
@@ -54,6 +54,13 @@ RecordContext *APIRecord::castToRecordContext(const APIRecord *Record) { } } +void RecordContext::stealRecordChain(RecordContext ) { + First = Other.First; + Last = Other.Last; + Other.First = nullptr; + Other.Last = nullptr; +} daniel-grumberg wrote: There is no harm in "stealing" an empty record chain, and it's not necessarily even semantically wrong, all it indicates is that the current RecordContext won't have any children during any traversals. Semantic problems would still be caught by having a test. https://github.com/llvm/llvm-project/pull/87772 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Update ExtractAPIConsumer.cpp (PR #88285)
https://github.com/daniel-grumberg approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/88285 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)
@@ -54,6 +54,13 @@ RecordContext *APIRecord::castToRecordContext(const APIRecord *Record) { } } +void RecordContext::stealRecordChain(RecordContext ) { + First = Other.First; + Last = Other.Last; + Other.First = nullptr; + Other.Last = nullptr; +} daniel-grumberg wrote: Maybe a better name for this would be `transferRecordChain`? https://github.com/llvm/llvm-project/pull/87772 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/87772 This changes the handling of anonymous TagDecls to the following rules: - If the TagDecl is embedded in the declaration for some VarDecl (this is the only possibility for RecordDecls), then pretend the child decls belong to the VarDecl - If it's an EnumDecl proceed as we did previously, i.e., embed it in the enclosing DeclContext. Additionally this fixes a few issues with declaration fragments not consistently including "{ ... }" for anonymous TagDecls. To make testing these additions easier this patch fixes some text declaration fragments merging issues and updates tests accordingly. >From f2755070ead054c56f7e9f9a2084ec40c10968bf Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Thu, 4 Apr 2024 18:33:25 +0100 Subject: [PATCH] [clang][ExtractAPI] Fix handling of anonymous TagDecls This changes the handling of anonymous TagDecls to the following rules: - If the TagDecl is embedded in the declaration for some VarDecl (this is the only possibility for RecordDecls), then pretend the child decls belong to the VarDecl - If it's an EnumDecl proceed as we did previously, i.e., embed it in the enclosing DeclContext. Additionally this fixes a few issues with declaration fragments not consistently including "{ ... }" for anonymous TagDecls. To make testing these additions easier this patch fixes some text declaration fragments merging issues and updates tests accordingly. --- clang/include/clang/ExtractAPI/API.h | 132 ++-- clang/include/clang/ExtractAPI/APIRecords.inc | 16 +- .../clang/ExtractAPI/DeclarationFragments.h | 84 ++- .../clang/ExtractAPI/ExtractAPIVisitor.h | 76 ++- clang/lib/ExtractAPI/API.cpp | 8 + clang/lib/ExtractAPI/DeclarationFragments.cpp | 17 +- .../Serialization/SymbolGraphSerializer.cpp | 8 + .../ExtractAPI/anonymous_record_no_typedef.c | 565 +- clang/test/ExtractAPI/enum.c | 12 +- clang/test/ExtractAPI/function_noexcepts.cpp | 18 +- clang/test/ExtractAPI/methods.cpp | 6 +- clang/test/ExtractAPI/objc_block.m| 48 +- .../ExtractAPI/typedef_anonymous_record.c | 4 +- clang/test/ExtractAPI/typedef_struct_enum.c | 2 +- 14 files changed, 427 insertions(+), 569 deletions(-) diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index 92cacf65c7d64e..05cfabd072a560 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -208,20 +208,20 @@ struct APIRecord { RK_ClassTemplate, RK_ClassTemplateSpecialization, RK_ClassTemplatePartialSpecialization, -RK_LastRecordContext, -RK_GlobalFunction, -RK_GlobalFunctionTemplate, -RK_GlobalFunctionTemplateSpecialization, +RK_StructField, +RK_UnionField, +RK_CXXField, +RK_StaticField, +RK_CXXFieldTemplate, RK_GlobalVariable, RK_GlobalVariableTemplate, RK_GlobalVariableTemplateSpecialization, RK_GlobalVariableTemplatePartialSpecialization, +RK_LastRecordContext, +RK_GlobalFunction, +RK_GlobalFunctionTemplate, +RK_GlobalFunctionTemplateSpecialization, RK_EnumConstant, -RK_StructField, -RK_UnionField, -RK_StaticField, -RK_CXXField, -RK_CXXFieldTemplate, RK_Concept, RK_CXXStaticMethod, RK_CXXInstanceMethod, @@ -321,6 +321,8 @@ class RecordContext { RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {} + void stealRecordChain(RecordContext ); + APIRecord::RecordKind getKind() const { return Kind; } struct record_iterator { @@ -475,7 +477,7 @@ struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord { }; /// This holds information associated with global functions. -struct GlobalVariableRecord : APIRecord { +struct GlobalVariableRecord : APIRecord, RecordContext { GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, LinkageInfo Linkage, const DocComment , @@ -483,23 +485,28 @@ struct GlobalVariableRecord : APIRecord { DeclarationFragments SubHeading, bool IsFromSystemHeader) : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc, std::move(Availability), Linkage, Comment, Declaration, - SubHeading, IsFromSystemHeader) {} + SubHeading, IsFromSystemHeader), +RecordContext(RK_GlobalVariable) {} GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name, - SymbolReference Parent, - - PresumedLoc Loc, AvailabilityInfo Availability, - LinkageInfo Linkage, const DocComment , + SymbolReference Parent, PresumedLoc Loc, + AvailabilityInfo Availability, LinkageInfo Linkage, +
[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)
daniel-grumberg wrote: Just reverted this due to buildbot failures in `Misc/warning-flags.c` will reenable shortly. https://github.com/llvm/llvm-project/pull/86676 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)
https://github.com/daniel-grumberg approved this pull request. https://github.com/llvm/llvm-project/pull/77716 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/86676 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)
https://github.com/daniel-grumberg deleted https://github.com/llvm/llvm-project/pull/86676 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)
@@ -119,20 +78,12 @@ static void WalkupFromMostDerivedType(LibClangExtractAPIVisitor , break; #include "clang/AST/DeclNodes.inc" } - - for (auto *Parent = D->getDeclContext(); Parent != nullptr; - Parent = Parent->getParent()) { -if (WalkupParentContext(Parent, Visitor)) daniel-grumberg wrote: Restore this logic for objc types? https://github.com/llvm/llvm-project/pull/86676 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)
@@ -54,63 +55,21 @@ struct LibClangExtractAPIVisitor if (!shouldDeclBeIncluded(Decl)) return true; -const ObjCInterfaceDecl *Interface = Decl->getClassInterface(); -StringRef Name = Interface->getName(); -StringRef USR = API.recordUSR(Decl); -PresumedLoc Loc = -Context.getSourceManager().getPresumedLoc(Decl->getLocation()); -LinkageInfo Linkage = Decl->getLinkageAndVisibility(); -DocComment Comment; -if (auto *RawComment = fetchRawCommentForDecl(Interface)) - Comment = RawComment->getFormattedLines(Context.getSourceManager(), - Context.getDiagnostics()); - -// Build declaration fragments and sub-heading by generating them for the -// interface. -DeclarationFragments Declaration = -DeclarationFragmentsBuilder::getFragmentsForObjCInterface(Interface); -DeclarationFragments SubHeading = -DeclarationFragmentsBuilder::getSubHeading(Decl); - -// Collect super class information. -SymbolReference SuperClass; -if (const auto *SuperClassDecl = Decl->getSuperClass()) { - SuperClass.Name = SuperClassDecl->getObjCRuntimeNameAsString(); - SuperClass.USR = API.recordUSR(SuperClassDecl); -} - -ObjCInterfaceRecord *ObjCInterfaceRecord = API.addObjCInterface( -Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, -Comment, Declaration, SubHeading, SuperClass, isInSystemHeader(Decl)); - -// Record all methods (selectors). This doesn't include automatically -// synthesized property methods. -recordObjCMethods(ObjCInterfaceRecord, Decl->methods()); -recordObjCProperties(ObjCInterfaceRecord, Decl->properties()); -recordObjCInstanceVariables(ObjCInterfaceRecord, Decl->ivars()); - -return true; +return VisitObjCInterfaceDecl(Decl->getClassInterface()); daniel-grumberg wrote: Restore logic to grab symbols defined only in the implementation. First visit the interface and then add the things only defined in the implementation block to the interface record. https://github.com/llvm/llvm-project/pull/86676 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)
@@ -50,17 +51,20 @@ TypedefUnderlyingTypeResolver::getSymbolReferenceForType(QualType Type, SmallString<128> TypeUSR; const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type); const TypedefType *TypedefTy = Type->getAs(); + StringRef OwningModuleName; if (TypeDecl) { if (!TypedefTy) TypeName = TypeDecl->getName().str(); clang::index::generateUSRForDecl(TypeDecl, TypeUSR); +if (auto *OwningModule = TypeDecl->getImportedOwningModule()) + OwningModuleName = API.copyString(OwningModule->Name); } else { clang::index::generateUSRForType(Type, Context, TypeUSR); } - return {API.copyString(TypeName), API.copyString(TypeUSR)}; + return {API.copyString(TypeName), API.copyString(TypeUSR), OwningModuleName}; daniel-grumberg wrote: TODO: Can this be expressed as APISet.createSymbolReference https://github.com/llvm/llvm-project/pull/86676 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)
@@ -1127,7 +1096,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization( .append("<", DeclarationFragments::FragmentKind::Text) .append(getFragmentsForTemplateArguments( Decl->getTemplateArgs().asArray(), Decl->getASTContext(), - Decl->getTemplateParameters()->asArray())) + Decl->getTemplateArgsAsWritten()->arguments())) daniel-grumberg wrote: Looks like the right thing to me! https://github.com/llvm/llvm-project/pull/77716 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Ensure typedef to pointer types are preserved (PR #78584)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/78584 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Add support C unions in non C++ parsing mode (PR #77451)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/77451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Add support C unions in non C++ parsing mode (PR #77451)
https://github.com/daniel-grumberg updated https://github.com/llvm/llvm-project/pull/77451 >From 8ff189e707a909f5228bce2042812a45a98d1e6c Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Tue, 9 Jan 2024 12:06:14 + Subject: [PATCH] [clang][ExtractAPI] Add support C unions in non C++ parsing mode Ensure that we generate correct symbol kinds and declaration fragments for unions in C and Objective-C parsing modes. rdar://120544091 --- clang/include/clang/ExtractAPI/API.h | 48 +-- .../clang/ExtractAPI/DeclarationFragments.h | 5 +- .../clang/ExtractAPI/ExtractAPIVisitor.h | 42 ++- .../ExtractAPI/Serialization/SerializerBase.h | 12 +- .../Serialization/SymbolGraphSerializer.h | 4 +- clang/lib/ExtractAPI/API.cpp | 35 ++- clang/lib/ExtractAPI/DeclarationFragments.cpp | 9 +- .../Serialization/SymbolGraphSerializer.cpp | 18 +- clang/test/ExtractAPI/union.c | 281 ++ 9 files changed, 380 insertions(+), 74 deletions(-) create mode 100644 clang/test/ExtractAPI/union.c diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index f4a6374161685e2..0a0f1bd1e95f7fe 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -169,6 +169,7 @@ struct APIRecord { RK_Enum, RK_StructField, RK_Struct, +RK_UnionField, RK_Union, RK_StaticField, RK_CXXField, @@ -478,17 +479,19 @@ struct EnumRecord : APIRecord { }; /// This holds information associated with struct fields. -struct StructFieldRecord : APIRecord { - StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc, +struct RecordFieldRecord : APIRecord { + RecordFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc, AvailabilityInfo Availability, const DocComment , DeclarationFragments Declaration, -DeclarationFragments SubHeading, bool IsFromSystemHeader) - : APIRecord(RK_StructField, USR, Name, Loc, std::move(Availability), +DeclarationFragments SubHeading, RecordKind Kind, +bool IsFromSystemHeader) + : APIRecord(Kind, USR, Name, Loc, std::move(Availability), LinkageInfo::none(), Comment, Declaration, SubHeading, IsFromSystemHeader) {} static bool classof(const APIRecord *Record) { -return Record->getKind() == RK_StructField; +return Record->getKind() == RK_StructField || + Record->getKind() == RK_UnionField; } private: @@ -496,19 +499,20 @@ struct StructFieldRecord : APIRecord { }; /// This holds information associated with structs. -struct StructRecord : APIRecord { - SmallVector> Fields; +struct RecordRecord : APIRecord { + SmallVector> Fields; - StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc, + RecordRecord(StringRef USR, StringRef Name, PresumedLoc Loc, AvailabilityInfo Availability, const DocComment , DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader) - : APIRecord(RK_Struct, USR, Name, Loc, std::move(Availability), + DeclarationFragments SubHeading, RecordKind Kind, + bool IsFromSystemHeader) + : APIRecord(Kind, USR, Name, Loc, std::move(Availability), LinkageInfo::none(), Comment, Declaration, SubHeading, IsFromSystemHeader) {} static bool classof(const APIRecord *Record) { -return Record->getKind() == RK_Struct; +return Record->getKind() == RK_Struct || Record->getKind() == RK_Union; } private: @@ -1266,30 +1270,31 @@ class APISet { DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader); - /// Create and add a struct field record into the API set. + /// Create and add a record field record into the API set. /// /// Note: the caller is responsible for keeping the StringRef \p Name and /// \p USR alive. APISet::copyString provides a way to copy strings into /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method /// to generate the USR for \c D and keep it alive in APISet. - StructFieldRecord * - addStructField(StructRecord *Struct, StringRef Name, StringRef USR, + RecordFieldRecord * + addRecordField(RecordRecord *Record, StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilityInfo Availability, const DocComment , DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader); + DeclarationFragments SubHeading, APIRecord::RecordKind Kind, + bool IsFromSystemHeader); - /// Create and add a struct record into the API set. + /// Create and add a record record into the API set. /// /// Note: the caller is responsible
[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/76823 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Ensure typedef to pointer types are preserved (PR #78584)
daniel-grumberg wrote: That and the typedef case before the pointer case. The pointer check would lead to extraneous desugaring in the fragments, i.e. you would get something like `struct Bar * value`, because the typedefs are also pointer types and therefore the typedef name would get bypassed in favor of the form "PointeeType *" https://github.com/llvm/llvm-project/pull/78584 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Ensure typedef to pointer types are preserved (PR #78584)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/78584 When generating declaration fragments for types that use typedefs to pointer types ensure that we keep the user-defined typedef form instead of desugaring the typedef. rdar://102137655 >From d3c4ca8092fcec8c8ebea26826cdf7e724edf7a7 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Thu, 18 Jan 2024 13:13:13 + Subject: [PATCH] [clang][ExtractAPI] Ensure typedef to pointer types are preserved When generating declaration fragments for types that use typedefs to pointer types ensure that we keep the user-defined typedef form instead of desugaring the typedef. rdar://102137655 --- clang/lib/ExtractAPI/DeclarationFragments.cpp | 80 ++--- clang/test/ExtractAPI/typedef.c | 280 ++ 2 files changed, 320 insertions(+), 40 deletions(-) diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index eb6eea0aaf5465..ae6b2eff5c8a29 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -252,6 +252,46 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( DeclarationFragments Fragments; + // An ElaboratedType is a sugar for types that are referred to using an + // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a + // qualified name, e.g., `N::M::type`, or both. + if (const ElaboratedType *ET = dyn_cast(T)) { +ElaboratedTypeKeyword Keyword = ET->getKeyword(); +if (Keyword != ElaboratedTypeKeyword::None) { + Fragments + .append(ElaboratedType::getKeywordName(Keyword), + DeclarationFragments::FragmentKind::Keyword) + .appendSpace(); +} + +if (const NestedNameSpecifier *NNS = ET->getQualifier()) + Fragments.append(getFragmentsForNNS(NNS, Context, After)); + +// After handling the elaborated keyword or qualified name, build +// declaration fragments for the desugared underlying type. +return Fragments.append(getFragmentsForType(ET->desugar(), Context, After)); + } + + // If the type is a typedefed type, get the underlying TypedefNameDecl for a + // direct reference to the typedef instead of the wrapped type. + + // 'id' type is a typedef for an ObjCObjectPointerType + // we treat it as a typedef + if (const TypedefType *TypedefTy = dyn_cast(T)) { +const TypedefNameDecl *Decl = TypedefTy->getDecl(); +TypedefUnderlyingTypeResolver TypedefResolver(Context); +std::string USR = TypedefResolver.getUSRForType(QualType(T, 0)); + +if (T->isObjCIdType()) { + return Fragments.append(Decl->getName(), + DeclarationFragments::FragmentKind::Keyword); +} + +return Fragments.append( +Decl->getName(), DeclarationFragments::FragmentKind::TypeIdentifier, +USR, TypedefResolver.getUnderlyingTypeDecl(QualType(T, 0))); + } + // Declaration fragments of a pointer type is the declaration fragments of // the pointee type followed by a `*`, if (T->isPointerType() && !T->isFunctionPointerType()) @@ -328,46 +368,6 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( getFragmentsForType(AT->getElementType(), Context, After)); } - // An ElaboratedType is a sugar for types that are referred to using an - // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a - // qualified name, e.g., `N::M::type`, or both. - if (const ElaboratedType *ET = dyn_cast(T)) { -ElaboratedTypeKeyword Keyword = ET->getKeyword(); -if (Keyword != ElaboratedTypeKeyword::None) { - Fragments - .append(ElaboratedType::getKeywordName(Keyword), - DeclarationFragments::FragmentKind::Keyword) - .appendSpace(); -} - -if (const NestedNameSpecifier *NNS = ET->getQualifier()) - Fragments.append(getFragmentsForNNS(NNS, Context, After)); - -// After handling the elaborated keyword or qualified name, build -// declaration fragments for the desugared underlying type. -return Fragments.append(getFragmentsForType(ET->desugar(), Context, After)); - } - - // If the type is a typedefed type, get the underlying TypedefNameDecl for a - // direct reference to the typedef instead of the wrapped type. - - // 'id' type is a typedef for an ObjCObjectPointerType - // we treat it as a typedef - if (const TypedefType *TypedefTy = dyn_cast(T)) { -const TypedefNameDecl *Decl = TypedefTy->getDecl(); -TypedefUnderlyingTypeResolver TypedefResolver(Context); -std::string USR = TypedefResolver.getUSRForType(QualType(T, 0)); - -if (T->isObjCIdType()) { - return Fragments.append(Decl->getName(), - DeclarationFragments::FragmentKind::Keyword); -} - -return Fragments.append( -Decl->getName(), DeclarationFragments::FragmentKind::TypeIdentifier, -USR,
[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)
https://github.com/daniel-grumberg approved this pull request. https://github.com/llvm/llvm-project/pull/76823 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)
@@ -16,67 +16,61 @@ #define LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H #include "clang/AST/Decl.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Error.h" #include "llvm/Support/VersionTuple.h" #include "llvm/Support/raw_ostream.h" - -using llvm::VersionTuple; +#include daniel-grumberg wrote: I don't think this is needed? https://github.com/llvm/llvm-project/pull/76823 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Add support C unions in non C++ parsing mode (PR #77451)
https://github.com/daniel-grumberg updated https://github.com/llvm/llvm-project/pull/77451 >From 9ed6ab49d39df12b95c65d48d065e82672dba48f Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Tue, 9 Jan 2024 12:06:14 + Subject: [PATCH] [clang][ExtractAPI] Add support C unions in non C++ parsing mode Ensure that we generate correct symbol kinds and declaration fragments for unions in C and Objective-C parsing modes. rdar://120544091 --- clang/include/clang/ExtractAPI/API.h | 48 +-- .../clang/ExtractAPI/DeclarationFragments.h | 5 +- .../clang/ExtractAPI/ExtractAPIVisitor.h | 39 ++- .../ExtractAPI/Serialization/SerializerBase.h | 12 +- .../Serialization/SymbolGraphSerializer.h | 4 +- clang/lib/ExtractAPI/API.cpp | 35 ++- clang/lib/ExtractAPI/DeclarationFragments.cpp | 9 +- .../Serialization/SymbolGraphSerializer.cpp | 18 +- clang/test/ExtractAPI/union.c | 281 ++ 9 files changed, 378 insertions(+), 73 deletions(-) create mode 100644 clang/test/ExtractAPI/union.c diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index b4c0e0ad39cdf2..a86654dd64bec5 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -169,6 +169,7 @@ struct APIRecord { RK_Enum, RK_StructField, RK_Struct, +RK_UnionField, RK_Union, RK_StaticField, RK_CXXField, @@ -478,17 +479,19 @@ struct EnumRecord : APIRecord { }; /// This holds information associated with struct fields. -struct StructFieldRecord : APIRecord { - StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc, +struct RecordFieldRecord : APIRecord { + RecordFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment , DeclarationFragments Declaration, -DeclarationFragments SubHeading, bool IsFromSystemHeader) - : APIRecord(RK_StructField, USR, Name, Loc, std::move(Availabilities), +DeclarationFragments SubHeading, RecordKind Kind, +bool IsFromSystemHeader) + : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), LinkageInfo::none(), Comment, Declaration, SubHeading, IsFromSystemHeader) {} static bool classof(const APIRecord *Record) { -return Record->getKind() == RK_StructField; +return Record->getKind() == RK_StructField || + Record->getKind() == RK_UnionField; } private: @@ -496,19 +499,20 @@ struct StructFieldRecord : APIRecord { }; /// This holds information associated with structs. -struct StructRecord : APIRecord { - SmallVector> Fields; +struct RecordRecord : APIRecord { + SmallVector> Fields; - StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc, + RecordRecord(StringRef USR, StringRef Name, PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment , DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader) - : APIRecord(RK_Struct, USR, Name, Loc, std::move(Availabilities), + DeclarationFragments SubHeading, RecordKind Kind, + bool IsFromSystemHeader) + : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), LinkageInfo::none(), Comment, Declaration, SubHeading, IsFromSystemHeader) {} static bool classof(const APIRecord *Record) { -return Record->getKind() == RK_Struct; +return Record->getKind() == RK_Struct || Record->getKind() == RK_Union; } private: @@ -1267,30 +1271,31 @@ class APISet { DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader); - /// Create and add a struct field record into the API set. + /// Create and add a record field record into the API set. /// /// Note: the caller is responsible for keeping the StringRef \p Name and /// \p USR alive. APISet::copyString provides a way to copy strings into /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method /// to generate the USR for \c D and keep it alive in APISet. - StructFieldRecord * - addStructField(StructRecord *Struct, StringRef Name, StringRef USR, + RecordFieldRecord * + addRecordField(RecordRecord *Record, StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment , DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader); + DeclarationFragments SubHeading, APIRecord::RecordKind Kind, + bool IsFromSystemHeader); - /// Create and add a struct record into the API set. + /// Create and add a record record into the API set. /// /// Note: the caller is
[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)
@@ -196,8 +196,7 @@ template class Foo {}; "spelling": "<" }, { - "kind": "typeIdentifier", - "preciseIdentifier": "c:t0.0", + "kind": "genericArgument", daniel-grumberg wrote: might be best to leave these as generic text fragments https://github.com/llvm/llvm-project/pull/77716 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)
@@ -1,50 +1,33 @@ #include "clang/ExtractAPI/AvailabilityInfo.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" +#include "clang/Basic/TargetInfo.h" #include "llvm/ADT/STLExtras.h" using namespace clang; using namespace extractapi; -AvailabilitySet::AvailabilitySet(const Decl *Decl) { - // Collect availability attributes from all redeclrations. - for (const auto *RD : Decl->redecls()) { -if (const auto *A = RD->getAttr()) { - if (!A->isImplicit()) { -this->Availabilities.clear(); -UnconditionallyUnavailable = true; - } -} +AvailabilityInfo::AvailabilityInfo(const Decl *Decl) { daniel-grumberg wrote: I would prefer if this wasn't a constructor but rather a static type method of with signature: ```c++ AvailabilityInfo createFromDecl(const Decl *D); ``` that way you don't have to do line 19-21 in that way. https://github.com/llvm/llvm-project/pull/76823 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Add support C unions in non C++ parsing mode (PR #77451)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/77451 Ensure that we generate correct symbol kinds and declaration fragments for unions in C and Objective-C parsing modes. rdar://120544091 >From 23d0713ba8003731cf03d2226c2cb3000411554f Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Tue, 9 Jan 2024 12:06:14 + Subject: [PATCH] [clang][ExtractAPI] Add support C unions in non C++ parsing mode Ensure that we generate correct symbol kinds and declaration fragments for unions in C and Objective-C parsing modes. rdar://120544091 --- clang/include/clang/ExtractAPI/API.h | 46 +-- .../clang/ExtractAPI/DeclarationFragments.h | 5 +- .../clang/ExtractAPI/ExtractAPIVisitor.h | 39 ++- .../ExtractAPI/Serialization/SerializerBase.h | 12 +- .../Serialization/SymbolGraphSerializer.h | 4 +- clang/lib/ExtractAPI/API.cpp | 35 ++- clang/lib/ExtractAPI/DeclarationFragments.cpp | 9 +- .../Serialization/SymbolGraphSerializer.cpp | 18 +- clang/test/ExtractAPI/union.c | 281 ++ 9 files changed, 377 insertions(+), 72 deletions(-) create mode 100644 clang/test/ExtractAPI/union.c diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index b4c0e0ad39cdf2..3bd3162da89a82 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -169,6 +169,7 @@ struct APIRecord { RK_Enum, RK_StructField, RK_Struct, +RK_UnionField, RK_Union, RK_StaticField, RK_CXXField, @@ -478,17 +479,19 @@ struct EnumRecord : APIRecord { }; /// This holds information associated with struct fields. -struct StructFieldRecord : APIRecord { - StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc, +struct RecordFieldRecord : APIRecord { + RecordFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment , DeclarationFragments Declaration, -DeclarationFragments SubHeading, bool IsFromSystemHeader) - : APIRecord(RK_StructField, USR, Name, Loc, std::move(Availabilities), +DeclarationFragments SubHeading, RecordKind Kind, +bool IsFromSystemHeader) + : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), LinkageInfo::none(), Comment, Declaration, SubHeading, IsFromSystemHeader) {} static bool classof(const APIRecord *Record) { -return Record->getKind() == RK_StructField; +return Record->getKind() == RK_StructField || + Record->getKind() == RK_UnionField; } private: @@ -496,19 +499,20 @@ struct StructFieldRecord : APIRecord { }; /// This holds information associated with structs. -struct StructRecord : APIRecord { - SmallVector> Fields; +struct RecordRecord : APIRecord { + SmallVector> Fields; - StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc, + RecordRecord(StringRef USR, StringRef Name, PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment , DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader) - : APIRecord(RK_Struct, USR, Name, Loc, std::move(Availabilities), + DeclarationFragments SubHeading, RecordKind Kind, + bool IsFromSystemHeader) + : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), LinkageInfo::none(), Comment, Declaration, SubHeading, IsFromSystemHeader) {} static bool classof(const APIRecord *Record) { -return Record->getKind() == RK_Struct; +return Record->getKind() == RK_Struct || Record->getKind() == RK_Union; } private: @@ -1267,17 +1271,18 @@ class APISet { DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader); - /// Create and add a struct field record into the API set. + /// Create and add a record field record into the API set. /// /// Note: the caller is responsible for keeping the StringRef \p Name and /// \p USR alive. APISet::copyString provides a way to copy strings into /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method /// to generate the USR for \c D and keep it alive in APISet. - StructFieldRecord * - addStructField(StructRecord *Struct, StringRef Name, StringRef USR, + RecordFieldRecord * + addRecordField(RecordRecord *Record, StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment , DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader); + DeclarationFragments SubHeading, APIRecord::RecordKind Kind, + bool IsFromSystemHeader); /// Create
[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)
@@ -256,14 +256,14 @@ struct APIRecord { APIRecord() = delete; APIRecord(RecordKind Kind, StringRef USR, StringRef Name, -PresumedLoc Location, AvailabilitySet Availabilities, +PresumedLoc Location, const AvailabilityInfo , daniel-grumberg wrote: Can you keep this as a value and bring back the `std::move` below, this allows to prevent unnecessary copies. https://github.com/llvm/llvm-project/pull/76823 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)
@@ -61,17 +61,17 @@ APISet::addNamespace(APIRecord *Parent, StringRef Name, StringRef USR, GlobalVariableRecord * APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc, - AvailabilitySet Availabilities, LinkageInfo Linkage, + const AvailabilityInfo , LinkageInfo Linkage, const DocComment , DeclarationFragments Fragments, DeclarationFragments SubHeading, bool IsFromSystemHeader) { return addTopLevelRecord(USRBasedLookupTable, GlobalVariables, USR, Name, Loc, - std::move(Availabilities), Linkage, Comment, - Fragments, SubHeading, IsFromSystemHeader); + Availability, Linkage, Comment, Fragments, daniel-grumberg wrote: Can you make sure that all of Availabilities are `std::move` https://github.com/llvm/llvm-project/pull/76823 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)
@@ -45,7 +45,7 @@ RecordTy *addTopLevelRecord(DenseMap , NamespaceRecord * APISet::addNamespace(APIRecord *Parent, StringRef Name, StringRef USR, - PresumedLoc Loc, AvailabilitySet Availability, + PresumedLoc Loc, const AvailabilityInfo , daniel-grumberg wrote: Can we keep these as plain values (i.e. just `AvailabilityInfo Availability`), this prevents the move operation below and leads to a copy. Additionally, this prevents copy ellision with how we pass the parameters in. https://github.com/llvm/llvm-project/pull/76823 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Allow serialization for ObjC++ headers (PR #74733)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/74733 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Allow serialization for ObjC++ headers (PR #74733)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/74733 rdar://79874441 >From 87d6b0fca621bae69102161fa4c3ebc003ae27bc Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Thu, 7 Dec 2023 14:52:47 + Subject: [PATCH] [clang][ExtractAPI] Allow serialization for ObjC++ headers rdar://79874441 --- .../Serialization/SymbolGraphSerializer.cpp | 3 +- clang/test/ExtractAPI/language.c | 101 +- 2 files changed, 101 insertions(+), 3 deletions(-) diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 931933b2bd1ac..d9675b0c94de3 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -199,9 +199,10 @@ StringRef getLanguageName(Language Lang) { return "objective-c"; case Language::CXX: return "c++"; + case Language::ObjCXX: +return "objective-c++"; // Unsupported language currently - case Language::ObjCXX: case Language::OpenCL: case Language::OpenCLCXX: case Language::CUDA: diff --git a/clang/test/ExtractAPI/language.c b/clang/test/ExtractAPI/language.c index 6facd18f5d981..fe98626c84613 100644 --- a/clang/test/ExtractAPI/language.c +++ b/clang/test/ExtractAPI/language.c @@ -4,29 +4,42 @@ // RUN: %t/c.reference.output.json.in >> %t/c.reference.output.json // RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \ // RUN: %t/objc.reference.output.json.in >> %t/objc.reference.output.json +// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \ +// RUN: %t/objcpp.reference.output.json.in >> %t/objcpp.reference.output.json -// RUN: %clang -extract-api -x c-header -target arm64-apple-macosx \ +// RUN: %clang_cc1 -extract-api -x c-header -triple arm64-apple-macosx \ // RUN: %t/c.h -o %t/c.output.json | FileCheck -allow-empty %s -// RUN: %clang -extract-api -x objective-c-header -target arm64-apple-macosx \ +// RUN: %clang_cc1 -extract-api -x objective-c-header -triple arm64-apple-macosx \ // RUN: %t/objc.h -o %t/objc.output.json | FileCheck -allow-empty %s +// RUN: %clang_cc1 -extract-api -x objective-c++-header -triple arm64-apple-macosx \ +// RUN: %t/objcpp.h -o %t/objcpp.output.json | FileCheck -allow-empty %s // Generator version is not consistent across test runs, normalize it. // RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ // RUN: %t/c.output.json >> %t/c.output-normalized.json // RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ // RUN: %t/objc.output.json >> %t/objc.output-normalized.json +// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ +// RUN: %t/objcpp.output.json >> %t/objcpp.output-normalized.json // RUN: diff %t/c.reference.output.json %t/c.output-normalized.json // RUN: diff %t/objc.reference.output.json %t/objc.output-normalized.json +// RUN: diff %t/objcpp.reference.output.json %t/objcpp.output-normalized.json // CHECK-NOT: error: // CHECK-NOT: warning: //--- c.h char c; +///expected-no-diagnostics //--- objc.h char objc; +///expected-no-diagnostics + +//--- objcpp.h +char objcpp; +///expected-no-diagnostics //--- c.reference.output.json.in { @@ -196,3 +209,87 @@ char objc; } ] } +//--- objcpp.reference.output.json.in +{ + "metadata": { +"formatVersion": { + "major": 0, + "minor": 5, + "patch": 3 +}, +"generator": "?" + }, + "module": { +"name": "", +"platform": { + "architecture": "arm64", + "operatingSystem": { +"minimumVersion": { + "major": 11, + "minor": 0, + "patch": 0 +}, +"name": "macosx" + }, + "vendor": "apple" +} + }, + "relationships": [], + "symbols": [ +{ + "accessLevel": "public", + "declarationFragments": [ +{ + "kind": "typeIdentifier", + "preciseIdentifier": "c:C", + "spelling": "char" +}, +{ + "kind": "text", + "spelling": " " +}, +{ + "kind": "identifier", + "spelling": "objcpp" +}, +{ + "kind": "text", + "spelling": ";" +} + ], + "identifier": { +"interfaceLanguage": "objective-c++", +"precise": "c:@objcpp" + }, + "kind": { +"displayName": "Global Variable", +"identifier": "objective-c++.var" + }, + "location": { +"position": { + "character": 5, + "line": 0 +}, +"uri": "file://INPUT_DIR/objcpp.h" + }, + "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "objcpp" + } +], +"subHeading": [ + { +"kind": "identifier", +"spelling": "objcpp" + } +], +"title": "objcpp" + }, +
[clang] [clang][ExtractAPI] Ensure LocationFileChecker doesn't try to traverse VFS when determining file path (PR #74071)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/74071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Ensure LocationFileChecker doesn't try to traverse VFS when determining file path (PR #74071)
daniel-grumberg wrote: Awesome! Let me know if you need any clarification as the semantic is now different from what it was originally and what it was after your patch. https://github.com/llvm/llvm-project/pull/74071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Ensure LocationFileChecker doesn't try to traverse VFS when determining file path (PR #74071)
daniel-grumberg wrote: Adding @compnerd since he committed (on behalf of someone else) the patch that caused this subtle problem in the first place. Do you know the original authors handle on GitHub? https://github.com/llvm/llvm-project/pull/74071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Ensure LocationFileChecker doesn't try to traverse VFS when determining file path (PR #74071)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/74071 As part of https://reviews.llvm.org/D154130 the logic of LocationFileChecker changed slightly to try and get the absolute external file path instead of the name as requested when the file was openened which would be before VFS mappings in our usage. Ensure that we only check against the name as requested instead of trying to generate the external canonical file path. rdar://115195433 >From 93f1bb149011be424ea2383ea21c99ba1ed595c8 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Fri, 1 Dec 2023 12:19:38 + Subject: [PATCH] [clang][ExtractAPI] Ensure LocationFileChecker doesn't try to traverse VFS when determining file path As part of https://reviews.llvm.org/D154130 the logic of LocationFileChecker changed slightly to try and get the absolute external file path instead of the name as requested when the file was openened which would be before VFS mappings in our usage. Ensure that we only check against the name as requested instead of trying to generate the external canonical file path. rdar://115195433 --- clang/lib/ExtractAPI/ExtractAPIConsumer.cpp | 11 +- .../test/ExtractAPI/vfs_redirected_include.m | 211 ++ 2 files changed, 219 insertions(+), 3 deletions(-) create mode 100644 clang/test/ExtractAPI/vfs_redirected_include.m diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index 3aba3bf44547cf6..fe282dfb19e8aa7 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -17,6 +17,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Basic/FileEntry.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -167,6 +168,12 @@ std::optional getRelativeIncludeName(const CompilerInstance , return std::nullopt; } +std::optional getRelativeIncludeName(const CompilerInstance , + FileEntryRef FE, + bool *IsQuoted = nullptr) { + return getRelativeIncludeName(CI, FE.getNameAsRequested(), IsQuoted); +} + struct LocationFileChecker { bool operator()(SourceLocation Loc) { // If the loc refers to a macro expansion we need to first get the file @@ -187,11 +194,9 @@ struct LocationFileChecker { if (ExternalFileEntries.count(*File)) return false; -StringRef FileName = SM.getFileManager().getCanonicalName(*File); - // Try to reduce the include name the same way we tried to include it. bool IsQuoted = false; -if (auto IncludeName = getRelativeIncludeName(CI, FileName, )) +if (auto IncludeName = getRelativeIncludeName(CI, *File, )) if (llvm::any_of(KnownFiles, [, ](const auto ) { return KnownFile.first.equals(*IncludeName) && diff --git a/clang/test/ExtractAPI/vfs_redirected_include.m b/clang/test/ExtractAPI/vfs_redirected_include.m new file mode 100644 index 000..9ba7e1dedb601eb --- /dev/null +++ b/clang/test/ExtractAPI/vfs_redirected_include.m @@ -0,0 +1,211 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t + +// Setup framework root +// RUN: mkdir -p %t/Frameworks/MyFramework.framework/Headers +// RUN: cp %t/MyFramework.h %t/Frameworks/MyFramework.framework/Headers/ +// RUN: cp %t/MyHeader.h %t/Frameworks/MyFramework.framework/Headers/ + +// RUN: sed -e "s@SRCROOT@%{/t:regex_replacement}@g" \ +// RUN: %t/reference.output.json.in >> %t/reference.output.json + +// Create VFS overlay from framework headers to SRCROOT +// RUN: sed -e "s@SRCROOT@%{/t:regex_replacement}@g" -e "s@DSTROOT@%{/t:regex_replacement}@g" \ +// RUN: %t/vfsoverlay.yaml.in >> %t/vfsoverlay.yaml + +// Input headers use paths to the framework root/DSTROOT +// RUN: %clang_cc1 -extract-api -v --product-name=MyFramework \ +// RUN: -triple arm64-apple-macosx \ +// RUN: -iquote%t -ivfsoverlay %t/vfsoverlay.yaml -F%t/Frameworks \ +// RUN: -x objective-c-header \ +// RUN: %t/Frameworks/MyFramework.framework/Headers/MyFramework.h \ +// RUN: %t/Frameworks/MyFramework.framework/Headers/MyHeader.h \ +// RUN: %t/QuotedHeader.h \ +// RUN: -o %t/output.json 2>&1 -verify | FileCheck -allow-empty %s + +// Generator version is not consistent across test runs, normalize it. +// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ +// RUN: %t/output.json >> %t/output-normalized.json +// RUN: diff %t/reference.output.json %t/output-normalized.json + +// CHECK: : +// CHECK-NEXT: #import +// CHECK-NEXT: #import +// CHECK-NEXT: #import "QuotedHeader.h" + +//--- vfsoverlay.yaml.in +{ +"case-sensitive": "false", +"roots": [ +{ +"contents": [ +{ +"external-contents": "SRCROOT/MyHeader.h", +
[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/73369 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/73369 Ensure that block types get represented correctly in declaration fragments, as block parameter names are important for documentation clients we need a separate system from getFragmentsForType in order to have access to full ParmVarDecls for the parameters. rdar://118257401 >From e0a9db8aa5e511e81836b5f8e59853c0b498cadf Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Fri, 24 Nov 2023 20:34:49 + Subject: [PATCH] [clang][ExtractAPI] Add support for blocks in declaration fragments Ensure that block types get represented correctly in declaration fragments, as block parameter names are important for documentation clients we need a separate system from getFragmentsForType in order to have access to full ParmVarDecls for the parameters. rdar://118257401 --- .../clang/ExtractAPI/DeclarationFragments.h | 6 + clang/lib/ExtractAPI/DeclarationFragments.cpp | 176 +++- clang/test/ExtractAPI/objc_block.m| 965 ++ clang/test/ExtractAPI/objc_category.m | 4 + clang/test/ExtractAPI/objc_id_protocol.m | 8 + clang/test/ExtractAPI/objc_interface.m| 4 + clang/test/ExtractAPI/objc_property.m | 24 + 7 files changed, 1159 insertions(+), 28 deletions(-) create mode 100644 clang/test/ExtractAPI/objc_block.m diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h b/clang/include/clang/ExtractAPI/DeclarationFragments.h index 316d83df13e9359..d719196b9a43ecb 100644 --- a/clang/include/clang/ExtractAPI/DeclarationFragments.h +++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h @@ -24,6 +24,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/TypeLoc.h" #include "clang/Basic/Specifiers.h" #include "clang/Lex/MacroInfo.h" #include "llvm/ADT/SmallVector.h" @@ -410,6 +411,11 @@ class DeclarationFragmentsBuilder { /// Build DeclarationFragments for a parameter variable declaration /// ParmVarDecl. static DeclarationFragments getFragmentsForParam(const ParmVarDecl *); + + static DeclarationFragments + getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc , + FunctionProtoTypeLoc , + DeclarationFragments ); }; template diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 02fa6cd6119ecac..eb6eea0aaf54655 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -15,6 +15,8 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/QualTypeNames.h" +#include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" #include "clang/Basic/OperatorKinds.h" #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" #include "clang/Index/USRGeneration.h" @@ -24,6 +26,40 @@ using namespace clang::extractapi; using namespace llvm; +namespace { + +void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo, + clang::FunctionTypeLoc , + clang::FunctionProtoTypeLoc ) { + if (!TSInfo) +return; + + clang::TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc(); + while (true) { +// Look through qualified types +if (auto QualifiedTL = TL.getAs()) { + TL = QualifiedTL.getUnqualifiedLoc(); + continue; +} + +if (auto AttrTL = TL.getAs()) { + TL = AttrTL.getModifiedLoc(); + continue; +} + +// Try to get the function prototype behind the block pointer type, +// then we're done. +if (auto BlockPtr = TL.getAs()) { + TL = BlockPtr.getPointeeLoc().IgnoreParens(); + Block = TL.getAs(); + BlockProto = TL.getAs(); +} +break; + } +} + +} // namespace + DeclarationFragments ::appendSpace() { if (!Fragments.empty()) { Fragment = Fragments.back(); @@ -218,7 +254,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( // Declaration fragments of a pointer type is the declaration fragments of // the pointee type followed by a `*`, - if (T->isPointerType()) + if (T->isPointerType() && !T->isFunctionPointerType()) return Fragments .append(getFragmentsForType(T->getPointeeType(), Context, After)) .append(" *", DeclarationFragments::FragmentKind::Text); @@ -449,10 +485,6 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const VarDecl *Var) { .append(VarDecl::getStorageClassSpecifierString(SC), DeclarationFragments::FragmentKind::Keyword) .appendSpace(); - QualType T = - Var->getTypeSourceInfo() - ? Var->getTypeSourceInfo()->getType() - : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType()); // Capture potential fragments that needs to be placed after the variable name // ``` @@ -460,8 +492,23 @@
[clang] ExtractAPI: use zero-based indices for line/column in symbol graph (PR #71753)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/71753 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ExtractAPI: use zero-based indices for line/column in symbol graph (PR #71753)
https://github.com/daniel-grumberg approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/71753 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Update availability serialization in SGF (PR #71418)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/71418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Update availability serialization in SGF (PR #71418)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/71418 The prevailiing symbol graph parsing library expects availability attributes to just be "introduced" instead of "introducedVersion" rdar://117823923 >From ad0c6afb7c728b2ea8ad83be22d670808d319783 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Mon, 6 Nov 2023 16:51:35 + Subject: [PATCH] [clang][ExtractAPI] Update availability serialization in SGF The prevailiing symbol graph parsing library expects availability attributes to just be "introduced" instead of "introducedVersion" rdar://117823923 --- .../Serialization/SymbolGraphSerializer.cpp | 6 +++--- clang/test/ExtractAPI/availability.c | 20 +-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 3c8668d26c60b76..f757522ef8e49db 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -177,11 +177,11 @@ serializeAvailability(const AvailabilitySet ) { if (AvailInfo.Unavailable) Availability["isUnconditionallyUnavailable"] = true; else { - serializeObject(Availability, "introducedVersion", + serializeObject(Availability, "introduced", serializeSemanticVersion(AvailInfo.Introduced)); - serializeObject(Availability, "deprecatedVersion", + serializeObject(Availability, "deprecated", serializeSemanticVersion(AvailInfo.Deprecated)); - serializeObject(Availability, "obsoletedVersion", + serializeObject(Availability, "obsoleted", serializeSemanticVersion(AvailInfo.Obsoleted)); } AvailabilityArray.emplace_back(std::move(Availability)); diff --git a/clang/test/ExtractAPI/availability.c b/clang/test/ExtractAPI/availability.c index 0c8cd3629f3fdee..5e3890df83563d4 100644 --- a/clang/test/ExtractAPI/availability.c +++ b/clang/test/ExtractAPI/availability.c @@ -127,7 +127,7 @@ void e(void) __attribute__((availability(tvos, unavailable))); "availability": [ { "domain": "macos", - "introducedVersion": { + "introduced": { "major": 12, "minor": 0, "patch": 0 @@ -200,18 +200,18 @@ void e(void) __attribute__((availability(tvos, unavailable))); "accessLevel": "public", "availability": [ { - "deprecatedVersion": { + "deprecated": { "major": 12, "minor": 0, "patch": 0 }, "domain": "macos", - "introducedVersion": { + "introduced": { "major": 11, "minor": 0, "patch": 0 }, - "obsoletedVersion": { + "obsoleted": { "major": 20, "minor": 0, "patch": 0 @@ -284,18 +284,18 @@ void e(void) __attribute__((availability(tvos, unavailable))); "accessLevel": "public", "availability": [ { - "deprecatedVersion": { + "deprecated": { "major": 12, "minor": 0, "patch": 0 }, "domain": "macos", - "introducedVersion": { + "introduced": { "major": 11, "minor": 0, "patch": 0 }, - "obsoletedVersion": { + "obsoleted": { "major": 20, "minor": 0, "patch": 0 @@ -303,7 +303,7 @@ void e(void) __attribute__((availability(tvos, unavailable))); }, { "domain": "ios", - "introducedVersion": { + "introduced": { "major": 13, "minor": 0, "patch": 0 @@ -311,7 +311,7 @@ void e(void) __attribute__((availability(tvos, unavailable))); }, { "domain": "tvos", - "introducedVersion": { + "introduced": { "major": 15, "minor": 0, "patch": 0 @@ -389,7 +389,7 @@ void e(void) __attribute__((availability(tvos, unavailable))); }, { "domain": "macos", - "introducedVersion": { + "introduced": { "major": 11, "minor": 0, "patch": 0 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg closed https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg updated https://github.com/llvm/llvm-project/pull/65481 >From d5054bcc53dad87232a4969e1a1f978b8d5a593d Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Wed, 6 Sep 2023 12:20:30 +0100 Subject: [PATCH] [clang] Prioritze decl comments from macro expansion site For declarations declared inside a macro, e.g.: ``` `#define MAKE_FUNC(suffix) \ /// Not selected doc comment \ void func_##suffix(void) { } /// Doc comment foo MAKE_FUNC(foo) /// Doc comment bar MAKE_FUNC(bar) Prefer the doc comment at the expansion site instead of the one defined in the macro. rdar://113995729 --- clang/lib/AST/ASTContext.cpp | 197 - clang/test/Index/annotate-comments-objc.m | 48 +++-- clang/unittests/Tooling/SourceCodeTest.cpp | 8 +- 3 files changed, 102 insertions(+), 151 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 27a675b83211775..72faea11349b48c 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -112,10 +112,10 @@ enum FloatingRank { Ibm128Rank }; -/// \returns location that is relevant when searching for Doc comments related -/// to \p D. -static SourceLocation getDeclLocForCommentSearch(const Decl *D, - SourceManager ) { +/// \returns The locations that are relevant when searching for Doc comments +/// related to \p D. +static SmallVector +getDeclLocsForCommentSearch(const Decl *D, SourceManager ) { assert(D); // User can not attach documentation to implicit declarations. @@ -167,115 +167,48 @@ static SourceLocation getDeclLocForCommentSearch(const Decl *D, isa(D)) return {}; + SmallVector Locations; // Find declaration location. // For Objective-C declarations we generally don't expect to have multiple // declarators, thus use declaration starting location as the "declaration // location". // For all other declarations multiple declarators are used quite frequently, // so we use the location of the identifier as the "declaration location". + SourceLocation BaseLocation; if (isa(D) || isa(D) || - isa(D) || - isa(D) || + isa(D) || isa(D) || isa(D) || // Allow association with Y across {} in `typedef struct X {} Y`. isa(D)) -return D->getBeginLoc(); +BaseLocation = D->getBeginLoc(); + else +BaseLocation = D->getLocation(); - const SourceLocation DeclLoc = D->getLocation(); - if (DeclLoc.isMacroID()) { -// There are (at least) three types of macros we care about here. -// -// 1. Macros that are used in the definition of a type outside the macro, -//with a comment attached at the macro call site. -//``` -//#define MAKE_NAME(Foo) Name##Foo -// -///// Comment is here, where we use the macro. -//struct MAKE_NAME(Foo) { -//int a; -//int b; -//}; -//``` -// 2. Macros that define whole things along with the comment. -//``` -//#define MAKE_METHOD(name) \ -// /** Comment is here, inside the macro. */ \ -// void name() {} -// -//struct S { -// MAKE_METHOD(f) -//} -//``` -// 3. Macros that both declare a type and name a decl outside the macro. -//``` -///// Comment is here, where we use the macro. -//typedef NS_ENUM(NSInteger, Size) { -//SizeWidth, -//SizeHeight -//}; -//``` -//In this case NS_ENUM declares am enum type, and uses the same name for -//the typedef declaration that appears outside the macro. The comment -//here should be applied to both declarations inside and outside the -//macro. -// -// We have found a Decl name that comes from inside a macro, but -// Decl::getLocation() returns the place where the macro is being called. -// If the declaration (and not just the name) resides inside the macro, -// then we want to map Decl::getLocation() into the macro to where the -// declaration and its attached comment (if any) were written. -// -// This mapping into the macro is done by mapping the location to its -// spelling location, however even if the declaration is inside a macro, -// the name's spelling can come from a macro argument (case 2 above). In -// this case mapping the location to the spelling location finds the -// argument's position (at `f` in MAKE_METHOD(`f`) above), which is not -// where the declaration and its comment are located. -// -// To avoid this issue, we make use of Decl::getBeginLocation() instead. -// While the declaration's position is where the name is written, the -// comment is always attached to the begining of the declaration, not to -// the name. -// -// In the first case, the begin location of the decl is outside
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg updated https://github.com/llvm/llvm-project/pull/65481 >From e9be513c357d7bb01a3acf69871e2e9889cb2079 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Wed, 6 Sep 2023 12:20:30 +0100 Subject: [PATCH] [clang] Prioritze decl comments from macro expansion site For declarations declared inside a macro, e.g.: ``` `#define MAKE_FUNC(suffix) \ /// Not selected doc comment \ void func_##suffix(void) { } /// Doc comment foo MAKE_FUNC(foo) /// Doc comment bar MAKE_FUNC(bar) Prefer the doc comment at the expansion site instead of the one defined in the macro. rdar://113995729 --- clang/lib/AST/ASTContext.cpp | 197 - clang/test/Index/annotate-comments-objc.m | 41 +++-- clang/unittests/Tooling/SourceCodeTest.cpp | 8 +- 3 files changed, 95 insertions(+), 151 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 27a675b83211775..72faea11349b48c 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -112,10 +112,10 @@ enum FloatingRank { Ibm128Rank }; -/// \returns location that is relevant when searching for Doc comments related -/// to \p D. -static SourceLocation getDeclLocForCommentSearch(const Decl *D, - SourceManager ) { +/// \returns The locations that are relevant when searching for Doc comments +/// related to \p D. +static SmallVector +getDeclLocsForCommentSearch(const Decl *D, SourceManager ) { assert(D); // User can not attach documentation to implicit declarations. @@ -167,115 +167,48 @@ static SourceLocation getDeclLocForCommentSearch(const Decl *D, isa(D)) return {}; + SmallVector Locations; // Find declaration location. // For Objective-C declarations we generally don't expect to have multiple // declarators, thus use declaration starting location as the "declaration // location". // For all other declarations multiple declarators are used quite frequently, // so we use the location of the identifier as the "declaration location". + SourceLocation BaseLocation; if (isa(D) || isa(D) || - isa(D) || - isa(D) || + isa(D) || isa(D) || isa(D) || // Allow association with Y across {} in `typedef struct X {} Y`. isa(D)) -return D->getBeginLoc(); +BaseLocation = D->getBeginLoc(); + else +BaseLocation = D->getLocation(); - const SourceLocation DeclLoc = D->getLocation(); - if (DeclLoc.isMacroID()) { -// There are (at least) three types of macros we care about here. -// -// 1. Macros that are used in the definition of a type outside the macro, -//with a comment attached at the macro call site. -//``` -//#define MAKE_NAME(Foo) Name##Foo -// -///// Comment is here, where we use the macro. -//struct MAKE_NAME(Foo) { -//int a; -//int b; -//}; -//``` -// 2. Macros that define whole things along with the comment. -//``` -//#define MAKE_METHOD(name) \ -// /** Comment is here, inside the macro. */ \ -// void name() {} -// -//struct S { -// MAKE_METHOD(f) -//} -//``` -// 3. Macros that both declare a type and name a decl outside the macro. -//``` -///// Comment is here, where we use the macro. -//typedef NS_ENUM(NSInteger, Size) { -//SizeWidth, -//SizeHeight -//}; -//``` -//In this case NS_ENUM declares am enum type, and uses the same name for -//the typedef declaration that appears outside the macro. The comment -//here should be applied to both declarations inside and outside the -//macro. -// -// We have found a Decl name that comes from inside a macro, but -// Decl::getLocation() returns the place where the macro is being called. -// If the declaration (and not just the name) resides inside the macro, -// then we want to map Decl::getLocation() into the macro to where the -// declaration and its attached comment (if any) were written. -// -// This mapping into the macro is done by mapping the location to its -// spelling location, however even if the declaration is inside a macro, -// the name's spelling can come from a macro argument (case 2 above). In -// this case mapping the location to the spelling location finds the -// argument's position (at `f` in MAKE_METHOD(`f`) above), which is not -// where the declaration and its comment are located. -// -// To avoid this issue, we make use of Decl::getBeginLocation() instead. -// While the declaration's position is where the name is written, the -// comment is always attached to the begining of the declaration, not to -// the name. -// -// In the first case, the begin location of the decl is outside the
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg updated https://github.com/llvm/llvm-project/pull/65481 >From 32155e8b5ac01242c3e16968f9a7c821d16b7007 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Wed, 6 Sep 2023 12:20:30 +0100 Subject: [PATCH 1/2] [clang] Prioritze decl comments from macro expansion site For declarations declared inside a macro, e.g.: ``` `#define MAKE_FUNC(suffix) \ /// Not selected doc comment \ void func_##suffix(void) { } /// Doc comment foo MAKE_FUNC(foo) /// Doc comment bar MAKE_FUNC(bar) Prefer the doc comment at the expansion site instead of the one defined in the macro. rdar://113995729 --- clang/lib/AST/ASTContext.cpp | 191 +++-- clang/test/Index/annotate-comments-objc.m | 12 +- clang/unittests/Tooling/SourceCodeTest.cpp | 5 +- 3 files changed, 70 insertions(+), 138 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 4b1d9e86797b778..074f59bd5a50411 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -112,10 +112,10 @@ enum FloatingRank { Ibm128Rank }; -/// \returns location that is relevant when searching for Doc comments related -/// to \p D. -static SourceLocation getDeclLocForCommentSearch(const Decl *D, - SourceManager ) { +/// \returns The locations that are relevant when searching for Doc comments +/// related to \p D. +static SmallVector +getDeclLocsForCommentSearch(const Decl *D, SourceManager ) { assert(D); // User can not attach documentation to implicit declarations. @@ -167,115 +167,41 @@ static SourceLocation getDeclLocForCommentSearch(const Decl *D, isa(D)) return {}; + SmallVector Locations; // Find declaration location. // For Objective-C declarations we generally don't expect to have multiple // declarators, thus use declaration starting location as the "declaration // location". // For all other declarations multiple declarators are used quite frequently, // so we use the location of the identifier as the "declaration location". + SourceLocation BaseLocation; if (isa(D) || isa(D) || - isa(D) || - isa(D) || + isa(D) || isa(D) || isa(D) || // Allow association with Y across {} in `typedef struct X {} Y`. isa(D)) -return D->getBeginLoc(); +BaseLocation = D->getBeginLoc(); + else +BaseLocation = D->getLocation(); - const SourceLocation DeclLoc = D->getLocation(); - if (DeclLoc.isMacroID()) { -// There are (at least) three types of macros we care about here. -// -// 1. Macros that are used in the definition of a type outside the macro, -//with a comment attached at the macro call site. -//``` -//#define MAKE_NAME(Foo) Name##Foo -// -///// Comment is here, where we use the macro. -//struct MAKE_NAME(Foo) { -//int a; -//int b; -//}; -//``` -// 2. Macros that define whole things along with the comment. -//``` -//#define MAKE_METHOD(name) \ -// /** Comment is here, inside the macro. */ \ -// void name() {} -// -//struct S { -// MAKE_METHOD(f) -//} -//``` -// 3. Macros that both declare a type and name a decl outside the macro. -//``` -///// Comment is here, where we use the macro. -//typedef NS_ENUM(NSInteger, Size) { -//SizeWidth, -//SizeHeight -//}; -//``` -//In this case NS_ENUM declares am enum type, and uses the same name for -//the typedef declaration that appears outside the macro. The comment -//here should be applied to both declarations inside and outside the -//macro. -// -// We have found a Decl name that comes from inside a macro, but -// Decl::getLocation() returns the place where the macro is being called. -// If the declaration (and not just the name) resides inside the macro, -// then we want to map Decl::getLocation() into the macro to where the -// declaration and its attached comment (if any) were written. -// -// This mapping into the macro is done by mapping the location to its -// spelling location, however even if the declaration is inside a macro, -// the name's spelling can come from a macro argument (case 2 above). In -// this case mapping the location to the spelling location finds the -// argument's position (at `f` in MAKE_METHOD(`f`) above), which is not -// where the declaration and its comment are located. -// -// To avoid this issue, we make use of Decl::getBeginLocation() instead. -// While the declaration's position is where the name is written, the -// comment is always attached to the begining of the declaration, not to -// the name. -// -// In the first case, the begin location of the decl is outside
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg edited https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
@@ -374,11 +374,10 @@ TEST(SourceCodeTest, getAssociatedRangeWithComments) { // Does not include comments when only the decl or the comment come from a // macro. daniel-grumberg wrote: Good spot, can't believe I removed the FIXME and not the comment explaining the FIXME https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg review_requested https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] Remove test with system header (PR #65646)
https://github.com/daniel-grumberg approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/65646 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg review_requested https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
@@ -179,103 +179,38 @@ static SourceLocation getDeclLocForCommentSearch(const Decl *D, isa(D) || // Allow association with Y across {} in `typedef struct X {} Y`. isa(D)) -return D->getBeginLoc(); +return {D->getBeginLoc()}; daniel-grumberg wrote: Yeah that is definitely neater, went for something along those lines in the updated patch. https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg updated https://github.com/llvm/llvm-project/pull/65481: >From 32155e8b5ac01242c3e16968f9a7c821d16b7007 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Wed, 6 Sep 2023 12:20:30 +0100 Subject: [PATCH] [clang] Prioritze decl comments from macro expansion site For declarations declared inside a macro, e.g.: ``` `#define MAKE_FUNC(suffix) \ /// Not selected doc comment \ void func_##suffix(void) { } /// Doc comment foo MAKE_FUNC(foo) /// Doc comment bar MAKE_FUNC(bar) Prefer the doc comment at the expansion site instead of the one defined in the macro. rdar://113995729 --- clang/lib/AST/ASTContext.cpp | 191 +++-- clang/test/Index/annotate-comments-objc.m | 12 +- clang/unittests/Tooling/SourceCodeTest.cpp | 5 +- 3 files changed, 70 insertions(+), 138 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 4b1d9e86797b778..074f59bd5a50411 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -112,10 +112,10 @@ enum FloatingRank { Ibm128Rank }; -/// \returns location that is relevant when searching for Doc comments related -/// to \p D. -static SourceLocation getDeclLocForCommentSearch(const Decl *D, - SourceManager ) { +/// \returns The locations that are relevant when searching for Doc comments +/// related to \p D. +static SmallVector +getDeclLocsForCommentSearch(const Decl *D, SourceManager ) { assert(D); // User can not attach documentation to implicit declarations. @@ -167,115 +167,41 @@ static SourceLocation getDeclLocForCommentSearch(const Decl *D, isa(D)) return {}; + SmallVector Locations; // Find declaration location. // For Objective-C declarations we generally don't expect to have multiple // declarators, thus use declaration starting location as the "declaration // location". // For all other declarations multiple declarators are used quite frequently, // so we use the location of the identifier as the "declaration location". + SourceLocation BaseLocation; if (isa(D) || isa(D) || - isa(D) || - isa(D) || + isa(D) || isa(D) || isa(D) || // Allow association with Y across {} in `typedef struct X {} Y`. isa(D)) -return D->getBeginLoc(); +BaseLocation = D->getBeginLoc(); + else +BaseLocation = D->getLocation(); - const SourceLocation DeclLoc = D->getLocation(); - if (DeclLoc.isMacroID()) { -// There are (at least) three types of macros we care about here. -// -// 1. Macros that are used in the definition of a type outside the macro, -//with a comment attached at the macro call site. -//``` -//#define MAKE_NAME(Foo) Name##Foo -// -///// Comment is here, where we use the macro. -//struct MAKE_NAME(Foo) { -//int a; -//int b; -//}; -//``` -// 2. Macros that define whole things along with the comment. -//``` -//#define MAKE_METHOD(name) \ -// /** Comment is here, inside the macro. */ \ -// void name() {} -// -//struct S { -// MAKE_METHOD(f) -//} -//``` -// 3. Macros that both declare a type and name a decl outside the macro. -//``` -///// Comment is here, where we use the macro. -//typedef NS_ENUM(NSInteger, Size) { -//SizeWidth, -//SizeHeight -//}; -//``` -//In this case NS_ENUM declares am enum type, and uses the same name for -//the typedef declaration that appears outside the macro. The comment -//here should be applied to both declarations inside and outside the -//macro. -// -// We have found a Decl name that comes from inside a macro, but -// Decl::getLocation() returns the place where the macro is being called. -// If the declaration (and not just the name) resides inside the macro, -// then we want to map Decl::getLocation() into the macro to where the -// declaration and its attached comment (if any) were written. -// -// This mapping into the macro is done by mapping the location to its -// spelling location, however even if the declaration is inside a macro, -// the name's spelling can come from a macro argument (case 2 above). In -// this case mapping the location to the spelling location finds the -// argument's position (at `f` in MAKE_METHOD(`f`) above), which is not -// where the declaration and its comment are located. -// -// To avoid this issue, we make use of Decl::getBeginLocation() instead. -// While the declaration's position is where the name is written, the -// comment is always attached to the begining of the declaration, not to -// the name. -// -// In the first case, the begin location of the decl is outside the
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
@@ -357,30 +292,37 @@ RawComment *ASTContext::getRawCommentForDeclNoCacheImpl( } RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { - const SourceLocation DeclLoc = getDeclLocForCommentSearch(D, SourceMgr); + const auto DeclLocs = getDeclLocsForCommentSearch(D, SourceMgr); daniel-grumberg wrote: This isn't a SourceLocation anymore but rather `SmallVector`, should I still explicitly put in the type? https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
daniel-grumberg wrote: This is a follow up on https://reviews.llvm.org/D142560 I couldn't find Dana on here to but in the the reviewer list. Maybe @gribozavr can help locate them? https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg review_requested https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg review_requested https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg review_requested https://github.com/llvm/llvm-project/pull/65481 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/65481: For declarations declared inside a macro, e.g.: ``` `#define MAKE_FUNC(suffix) \ /// Not selected doc comment \ void func_##suffix(void) { } /// Doc comment foo MAKE_FUNC(foo) /// Doc comment bar MAKE_FUNC(bar) Prefer the doc comment at the expansion site instead of the one defined in the macro. rdar://113995729 >From 7bfaa68b33e254d8a77b6dab2db7e89ef24b1175 Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Wed, 6 Sep 2023 12:20:30 +0100 Subject: [PATCH] [clang] Prioritze decl comments from macro expansion site For declarations declared inside a macro, e.g.: ``` `#define MAKE_FUNC(suffix) \ /// Not selected doc comment \ void func_##suffix(void) { } /// Doc comment foo MAKE_FUNC(foo) /// Doc comment bar MAKE_FUNC(bar) Prefer the doc comment at the expansion site instead of the one defined in the macro. rdar://113995729 --- clang/lib/AST/ASTContext.cpp | 191 -- clang/test/Index/annotate-comments-objc.m | 5 +- 2 files changed, 70 insertions(+), 126 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 4b1d9e86797b778..304312d3a8acfa5 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -112,10 +112,10 @@ enum FloatingRank { Ibm128Rank }; -/// \returns location that is relevant when searching for Doc comments related -/// to \p D. -static SourceLocation getDeclLocForCommentSearch(const Decl *D, - SourceManager ) { +/// \returns The locations that are relevant when searching for Doc comments +/// related to \p D. +static SmallVector +getDeclLocsForCommentSearch(const Decl *D, SourceManager ) { assert(D); // User can not attach documentation to implicit declarations. @@ -179,103 +179,38 @@ static SourceLocation getDeclLocForCommentSearch(const Decl *D, isa(D) || // Allow association with Y across {} in `typedef struct X {} Y`. isa(D)) -return D->getBeginLoc(); +return {D->getBeginLoc()}; const SourceLocation DeclLoc = D->getLocation(); if (DeclLoc.isMacroID()) { -// There are (at least) three types of macros we care about here. -// -// 1. Macros that are used in the definition of a type outside the macro, -//with a comment attached at the macro call site. -//``` -//#define MAKE_NAME(Foo) Name##Foo -// -///// Comment is here, where we use the macro. -//struct MAKE_NAME(Foo) { -//int a; -//int b; -//}; -//``` -// 2. Macros that define whole things along with the comment. -//``` -//#define MAKE_METHOD(name) \ -// /** Comment is here, inside the macro. */ \ -// void name() {} -// -//struct S { -// MAKE_METHOD(f) -//} -//``` -// 3. Macros that both declare a type and name a decl outside the macro. -//``` -///// Comment is here, where we use the macro. -//typedef NS_ENUM(NSInteger, Size) { -//SizeWidth, -//SizeHeight -//}; -//``` -//In this case NS_ENUM declares am enum type, and uses the same name for -//the typedef declaration that appears outside the macro. The comment -//here should be applied to both declarations inside and outside the -//macro. -// -// We have found a Decl name that comes from inside a macro, but -// Decl::getLocation() returns the place where the macro is being called. -// If the declaration (and not just the name) resides inside the macro, -// then we want to map Decl::getLocation() into the macro to where the -// declaration and its attached comment (if any) were written. -// -// This mapping into the macro is done by mapping the location to its -// spelling location, however even if the declaration is inside a macro, -// the name's spelling can come from a macro argument (case 2 above). In -// this case mapping the location to the spelling location finds the -// argument's position (at `f` in MAKE_METHOD(`f`) above), which is not -// where the declaration and its comment are located. -// -// To avoid this issue, we make use of Decl::getBeginLocation() instead. -// While the declaration's position is where the name is written, the -// comment is always attached to the begining of the declaration, not to -// the name. -// -// In the first case, the begin location of the decl is outside the macro, -// at the location of `typedef`. This is where the comment is found as -// well. The begin location is not inside a macro, so it's spelling -// location is the same. -// -// In the second case, the begin location of the decl is the call to the -// macro, at `MAKE_METHOD`.
[clang] 06ff977 - [clang][ExtractAPI] Refactor serializer to the CRTP
Author: Erick Velez Date: 2023-05-30T19:00:35+01:00 New Revision: 06ff9770477d8c7378047b0171db4b25eba5d8dd URL: https://github.com/llvm/llvm-project/commit/06ff9770477d8c7378047b0171db4b25eba5d8dd DIFF: https://github.com/llvm/llvm-project/commit/06ff9770477d8c7378047b0171db4b25eba5d8dd.diff LOG: [clang][ExtractAPI] Refactor serializer to the CRTP Refactor SerializerBase and SymbolGraphSerializer to use a visitor pattern described by the CRTP. Reviewed By: dang Differential Revision: https://reviews.llvm.org/D151477 Added: Modified: clang/include/clang/ExtractAPI/Serialization/SerializerBase.h clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h clang/lib/ExtractAPI/CMakeLists.txt clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp Removed: clang/lib/ExtractAPI/Serialization/SerializerBase.cpp diff --git a/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h b/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h index d8aa826e3f4f6..006e92be29555 100644 --- a/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h +++ b/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h @@ -7,7 +7,7 @@ //===--===// /// /// \file -/// This file defines the ExtractAPI APISerializer interface. +/// This file defines the ExtractAPI APISetVisitor interface. /// //===--===// @@ -15,47 +15,107 @@ #define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H #include "clang/ExtractAPI/API.h" -#include "clang/ExtractAPI/APIIgnoresList.h" -#include "llvm/Support/raw_ostream.h" namespace clang { namespace extractapi { -/// Common options to customize the serializer output. -struct APISerializerOption { - /// Do not include unnecessary whitespaces to save space. - bool Compact; -}; - -/// The base interface of serializers for API information. -class APISerializer { +/// The base interface of visitors for API information. +template class APISetVisitor { public: - /// Serialize the API information to \p os. - virtual void serialize(raw_ostream ) = 0; + void traverseAPISet() { +getDerived()->traverseGlobalVariableRecords(); -protected: - const APISet +getDerived()->traverseGlobalFunctionRecords(); + +getDerived()->traverseEnumRecords(); + +getDerived()->traverseStructRecords(); + +getDerived()->traverseObjCInterfaces(); + +getDerived()->traverseObjCProtocols(); + +getDerived()->traverseMacroDefinitionRecords(); + +getDerived()->traverseTypedefRecords(); + } + + void traverseGlobalFunctionRecords() { +for (const auto : API.getGlobalFunctions()) + getDerived()->visitGlobalFunctionRecord(*GlobalFunction.second); + } + + void traverseGlobalVariableRecords() { +for (const auto : API.getGlobalVariables()) + getDerived()->visitGlobalVariableRecord(*GlobalVariable.second); + } + + void traverseEnumRecords() { +for (const auto : API.getEnums()) + getDerived()->visitEnumRecord(*Enum.second); + } - /// The list of symbols to ignore. - /// - /// Note: This should be consulted before emitting a symbol. - const APIIgnoresList + void traverseStructRecords() { +for (const auto : API.getStructs()) + getDerived()->visitStructRecord(*Struct.second); + } - APISerializerOption Options; + void traverseObjCInterfaces() { +for (const auto : API.getObjCInterfaces()) + getDerived()->visitObjCContainerRecord(*Interface.second); + } + + void traverseObjCProtocols() { +for (const auto : API.getObjCProtocols()) + getDerived()->visitObjCContainerRecord(*Protocol.second); + } + + void traverseMacroDefinitionRecords() { +for (const auto : API.getMacros()) + getDerived()->visitMacroDefinitionRecord(*Macro.second); + } + + void traverseTypedefRecords() { +for (const auto : API.getTypedefs()) + getDerived()->visitTypedefRecord(*Typedef.second); + } + + /// Visit a global function record. + void visitGlobalFunctionRecord(const GlobalFunctionRecord ){}; + + /// Visit a global variable record. + void visitGlobalVariableRecord(const GlobalVariableRecord ){}; + + /// Visit an enum record. + void visitEnumRecord(const EnumRecord ){}; + + /// Visit a struct record. + void visitStructRecord(const StructRecord ){}; + + /// Visit an Objective-C container record. + void visitObjCContainerRecord(const ObjCContainerRecord ){}; + + /// Visit a macro definition record. + void visitMacroDefinitionRecord(const MacroDefinitionRecord ){}; + + /// Visit a typedef record. + void visitTypedefRecord(const TypedefRecord ){}; + +protected: + const APISet public: - APISerializer() = delete; - APISerializer(const APISerializer &) = delete; - APISerializer(APISerializer &&) = delete; -
[clang] 3ac5509 - [clang][ExtractAPI] Complete declaration fragments for TagDecl types defined in a typedef
Author: ruturaj4 Date: 2023-04-13T17:55:45+01:00 New Revision: 3ac550984e83c2478772c800b1f1b5cffd63a10d URL: https://github.com/llvm/llvm-project/commit/3ac550984e83c2478772c800b1f1b5cffd63a10d DIFF: https://github.com/llvm/llvm-project/commit/3ac550984e83c2478772c800b1f1b5cffd63a10d.diff LOG: [clang][ExtractAPI] Complete declaration fragments for TagDecl types defined in a typedef enums and structs declared inside typedefs have incorrect declaration fragments, where the typedef keyword and other syntax is missing. For the following struct: typedef struct Test { int hello; } Test; The produced declaration is: "declarationFragments": [ { "kind": "keyword", "spelling": "struct" }, { "kind": "text", "spelling": " " }, { "kind": "identifier", "spelling": "Test" } ], instead the declaration fragments should represent the following typedef struct Test { … } Test; This patch removes the condition in SymbolGraphSerializer.cpp file and completes declaration fragments Reviewed By: dang Differential Revision: https://reviews.llvm.org/D146385 Added: clang/test/ExtractAPI/typedef_struct_enum.c Modified: clang/include/clang/ExtractAPI/DeclarationFragments.h clang/include/clang/ExtractAPI/ExtractAPIVisitor.h Removed: diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h b/clang/include/clang/ExtractAPI/DeclarationFragments.h index a5db4d23e8b55..90121a138175c 100644 --- a/clang/include/clang/ExtractAPI/DeclarationFragments.h +++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h @@ -99,6 +99,25 @@ class DeclarationFragments { const std::vector () const { return Fragments; } + // Add a new Fragment to the beginning of the Fragments. + DeclarationFragments (StringRef Spelling, FragmentKind Kind, +StringRef PreciseIdentifier = "", +const Decl *Declaration = nullptr) { +Fragments.emplace(Fragments.begin(), Spelling, Kind, PreciseIdentifier, + Declaration); +return *this; + } + + DeclarationFragments (DeclarationFragments &) { +Fragments.insert(Fragments.begin(), + std::make_move_iterator(Other.Fragments.begin()), + std::make_move_iterator(Other.Fragments.end())); +Other.Fragments.clear(); +return *this; + } + + void removeLast() { Fragments.pop_back(); } + /// Append a new Fragment to the end of the Fragments. /// /// \returns a reference to the DeclarationFragments object itself after diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index a31648b80195a..57f2c413545c0 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -22,6 +22,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/ExtractAPI/API.h" #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" +#include "llvm/ADT/StringRef.h" #include namespace clang { @@ -105,6 +106,24 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { } }; +template +static void modifyRecords(const T , const StringRef ) { + for (const auto : Records) { +if (Name == Record.second.get()->Name) { + Record.second.get()->Declaration.removeLast(); + Record.second.get() + ->Declaration + .appendFront(" ", DeclarationFragments::FragmentKind::Text) + .appendFront("typedef", DeclarationFragments::FragmentKind::Keyword, + "", nullptr) + .append(" { ... } ", DeclarationFragments::FragmentKind::Text) + .append(Name, DeclarationFragments::FragmentKind::Identifier) + .append(";", DeclarationFragments::FragmentKind::Text); + break; +} + } +} + template bool ExtractAPIVisitorBase::VisitVarDecl(const VarDecl *Decl) { // skip function parameters. @@ -401,6 +420,21 @@ bool ExtractAPIVisitorBase::VisitTypedefNameDecl( if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) return true; + // Add the notion of typedef for tag type (struct or enum) of the same name. + if (const ElaboratedType *ET = + dyn_cast(Decl->getUnderlyingType())) { +if (const TagType *TagTy = dyn_cast(ET->desugar())) { + if (Decl->getName() == TagTy->getDecl()->getName()) { +if (TagTy->getDecl()->isStruct()) { + modifyRecords(API.getStructs(), Decl->getName()); +} +if (TagTy->getDecl()->isEnum()) { + modifyRecords(API.getEnums(), Decl->getName()); +} + } +} + } + PresumedLoc Loc = Context.getSourceManager().getPresumedLoc(Decl->getLocation()); StringRef Name = Decl->getName(); diff --git a/clang/test/ExtractAPI/typedef_struct_enum.c b/clang/test/ExtractAPI/typedef_struct_enum.c new file mode
[clang] 142c3d9 - [clang][ExtractAPI] Reland ExtractAPI for libclang improvements
Author: Daniel Grumberg Date: 2023-03-30T18:13:58+01:00 New Revision: 142c3d9d1414847fd154c300ff12505283027505 URL: https://github.com/llvm/llvm-project/commit/142c3d9d1414847fd154c300ff12505283027505 DIFF: https://github.com/llvm/llvm-project/commit/142c3d9d1414847fd154c300ff12505283027505.diff LOG: [clang][ExtractAPI] Reland ExtractAPI for libclang improvements This relands the changes that were originally introduced by: - https://reviews.llvm.org/D146656 - https://reviews.llvm.org/D147138 This also fixes the leak that led to these changes being reverted Differential Revision: https://reviews.llvm.org/D147234 Added: clang/include/clang/ExtractAPI/TypedefUnderlyingTypeResolver.h Modified: clang/include/clang/ExtractAPI/ExtractAPIVisitor.h clang/lib/ExtractAPI/CMakeLists.txt clang/lib/ExtractAPI/DeclarationFragments.cpp clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp clang/test/Index/extract-api-cursor.m clang/test/Index/extract-api-usr.m clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CXExtractAPI.cpp Removed: clang/lib/ExtractAPI/ExtractAPIVisitor.cpp clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.h diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index f6546fb4776a6..a31648b80195a 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -14,24 +14,27 @@ #ifndef LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H #define LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H +#include "llvm/ADT/FunctionExtras.h" + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ParentMapContext.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceManager.h" #include "clang/ExtractAPI/API.h" -#include "llvm/ADT/FunctionExtras.h" +#include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" +#include namespace clang { namespace extractapi { +namespace impl { -/// The RecursiveASTVisitor to traverse symbol declarations and collect API -/// information. -class ExtractAPIVisitor : public RecursiveASTVisitor { -public: - ExtractAPIVisitor(ASTContext , -llvm::unique_function LocationChecker, -APISet ) - : Context(Context), API(API), -LocationChecker(std::move(LocationChecker)) {} +template +class ExtractAPIVisitorBase : public RecursiveASTVisitor { +protected: + ExtractAPIVisitorBase(ASTContext , APISet ) + : Context(Context), API(API) {} +public: const APISet () const { return API; } bool VisitVarDecl(const VarDecl *Decl); @@ -50,7 +53,11 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl); -private: + bool shouldDeclBeIncluded(const Decl *Decl) const; + + const RawComment *fetchRawCommentForDecl(const Decl *Decl) const; + +protected: /// Collect API information for the enum constants and associate with the /// parent enum. void recordEnumConstants(EnumRecord *EnumRecord, @@ -77,9 +84,582 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { void recordObjCProtocols(ObjCContainerRecord *Container, ObjCInterfaceDecl::protocol_range Protocols); + ASTContext APISet - llvm::unique_function LocationChecker; + + StringRef getTypedefName(const TagDecl *Decl) { +if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl()) + return TypedefDecl->getName(); + +return {}; + } + + bool isInSystemHeader(const Decl *D) { +return Context.getSourceManager().isInSystemHeader(D->getLocation()); + } + +private: + Derived () { +return *static_cast(this); + } +}; + +template +bool ExtractAPIVisitorBase::VisitVarDecl(const VarDecl *Decl) { + // skip function parameters. + if (isa(Decl)) +return true; + + // Skip non-global variables in records (struct/union/class). + if (Decl->getDeclContext()->isRecord()) +return true; + + // Skip local variables inside function or method. + if (!Decl->isDefinedOutsideFunctionOrMethod()) +return true; + + // If this is a template but not specialization or instantiation, skip. + if (Decl->getASTContext().getTemplateOrSpecializationInfo(Decl) && + Decl->getTemplateSpecializationKind() == TSK_Undeclared) +return true; + + if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) +return true; + + // Collect symbol information. + StringRef Name = Decl->getName(); + StringRef USR = API.recordUSR(Decl); + PresumedLoc Loc = + Context.getSourceManager().getPresumedLoc(Decl->getLocation()); + LinkageInfo Linkage = Decl->getLinkageAndVisibility(); + DocComment Comment; + if (auto *RawComment = +
[clang] 1cfe1e7 - [clang][ExtractAPI] Add queried symbol to parent contexts in libclang
Author: Daniel Grumberg Date: 2023-03-29T16:32:26+01:00 New Revision: 1cfe1e732ad8e8148f6fa8fc0f0c86f4b965d567 URL: https://github.com/llvm/llvm-project/commit/1cfe1e732ad8e8148f6fa8fc0f0c86f4b965d567 DIFF: https://github.com/llvm/llvm-project/commit/1cfe1e732ad8e8148f6fa8fc0f0c86f4b965d567.diff LOG: [clang][ExtractAPI] Add queried symbol to parent contexts in libclang Ensure that the current symbol is added to the parent contexts in the output of libclang function for generating symbol graphs for single symbols. Differential Revision: https://reviews.llvm.org/D147138 Added: Modified: clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/test/Index/extract-api-cursor.m clang/test/Index/extract-api-usr.m Removed: diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 8a98f5cf0c71f..7676c74af6869 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -547,10 +547,6 @@ Array generateParentContexts(const RecordTy , const APISet , serializeParentContext(PC, Lang)); }); - // The last component would be the record itself so let's remove it. - if (!ParentContexts.empty()) -ParentContexts.pop_back(); - return ParentContexts; } diff --git a/clang/test/Index/extract-api-cursor.m b/clang/test/Index/extract-api-cursor.m index 16844ca1674ee..1b27b6f61437b 100644 --- a/clang/test/Index/extract-api-cursor.m +++ b/clang/test/Index/extract-api-cursor.m @@ -34,7 +34,7 @@ - (void)derivedMethodWithValue:(id)value { @end // RUN: c-index-test -single-symbol-sgf-at=%s:4:9 local %s | FileCheck -check-prefix=CHECK-FOO %s -// CHECK-FOO: "parentContexts":[] +// CHECK-FOO: "parentContexts":[{"kind":"objective-c.struct","name":"Foo","usr":"c:@S@Foo"}] // CHECK-FOO: "relatedSymbols":[] // CHECK-FOO: "relationships":[] // CHECK-FOO: "text":"Foo docs" @@ -42,7 +42,7 @@ - (void)derivedMethodWithValue:(id)value { // CHECK-FOO: "title":"Foo" // RUN: c-index-test -single-symbol-sgf-at=%s:6:9 local %s | FileCheck -check-prefix=CHECK-BAR %s -// CHECK-BAR: "parentContexts":[{"kind":"objective-c.struct","name":"Foo","usr":"c:@S@Foo"}] +// CHECK-BAR: "parentContexts":[{"kind":"objective-c.struct","name":"Foo","usr":"c:@S@Foo"},{"kind":"objective-c.property","name":"bar","usr":"c:@S@Foo@FI@bar"}] // CHECK-BAR: "relatedSymbols":[] // CHECK-BAR: "relationships":[{"kind":"memberOf","source":"c:@S@Foo@FI@bar","target":"c:@S@Foo" // CHECK-BAR: "text":"Bar docs" @@ -50,7 +50,7 @@ - (void)derivedMethodWithValue:(id)value { // CHECK-BAR: "title":"bar" // RUN: c-index-test -single-symbol-sgf-at=%s:10:11 local %s | FileCheck -check-prefix=CHECK-BASE %s -// CHECK-BASE: "parentContexts":[] +// CHECK-BASE: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}] // CHECK-BASE: "relatedSymbols":[] // CHECK-BASE: "relationships":[] // CHECK-BASE: "text":"Base docs" @@ -58,7 +58,7 @@ - (void)derivedMethodWithValue:(id)value { // CHECK-BASE: "title":"Base" // RUN: c-index-test -single-symbol-sgf-at=%s:12:25 local %s | FileCheck -check-prefix=CHECK-BASE-PROP %s -// CHECK-BASE-PROP: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}] +// CHECK-BASE-PROP: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"},{"kind":"objective-c.property","name":"baseProperty","usr":"c:objc(cs)Base(py)baseProperty"}] // CHECK-BASE-PROP: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" // CHECK-BASE-PROP: "isSystem":false // CHECK-BASE-PROP: "usr":"c:@S@Foo"}] @@ -68,7 +68,7 @@ - (void)derivedMethodWithValue:(id)value { // CHECK-BASE-PROP: "title":"baseProperty" // RUN: c-index-test -single-symbol-sgf-at=%s:15:9 local %s | FileCheck -check-prefix=CHECK-BASE-METHOD %s -// CHECK-BASE-METHOD: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}] +// CHECK-BASE-METHOD: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"},{"kind":"objective-c.method","name":"baseMethodWithArg:","usr":"c:objc(cs)Base(im)baseMethodWithArg:"}] // CHECK-BASE-METHOD: "relatedSymbols":[] // CHECK-BASE-METHOD: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(im)baseMethodWithArg:","target":"c:objc(cs)Base" // CHECK-BASE-METHOD: "text":"Base method docs" @@ -76,7 +76,7 @@ - (void)derivedMethodWithValue:(id)value { // CHECK-BASE-METHOD: "title":"baseMethodWithArg:" // RUN: c-index-test -single-symbol-sgf-at=%s:19:11 local %s | FileCheck -check-prefix=CHECK-PROTOCOL %s -// CHECK-PROTOCOL: "parentContexts":[] +// CHECK-PROTOCOL:
[clang] 7911647 - Revert "Revert ExtractAPI from https://reviews.llvm.org/D146656"
Author: Daniel Grumberg Date: 2023-03-29T10:51:13+01:00 New Revision: 79116475124112051625b1a0665e35c861bb13fd URL: https://github.com/llvm/llvm-project/commit/79116475124112051625b1a0665e35c861bb13fd DIFF: https://github.com/llvm/llvm-project/commit/79116475124112051625b1a0665e35c861bb13fd.diff LOG: Revert "Revert ExtractAPI from https://reviews.llvm.org/D146656; This reverts commit 158a431227a876306fe5838936413dd51588d0c6. Added: clang/include/clang/ExtractAPI/TypedefUnderlyingTypeResolver.h Modified: clang/include/clang/ExtractAPI/ExtractAPIVisitor.h clang/lib/ExtractAPI/CMakeLists.txt clang/lib/ExtractAPI/DeclarationFragments.cpp clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp clang/test/Index/extract-api-cursor.m clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CXExtractAPI.cpp Removed: clang/lib/ExtractAPI/ExtractAPIVisitor.cpp clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.h diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index f6546fb4776a6..a31648b80195a 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -14,24 +14,27 @@ #ifndef LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H #define LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H +#include "llvm/ADT/FunctionExtras.h" + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ParentMapContext.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceManager.h" #include "clang/ExtractAPI/API.h" -#include "llvm/ADT/FunctionExtras.h" +#include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" +#include namespace clang { namespace extractapi { +namespace impl { -/// The RecursiveASTVisitor to traverse symbol declarations and collect API -/// information. -class ExtractAPIVisitor : public RecursiveASTVisitor { -public: - ExtractAPIVisitor(ASTContext , -llvm::unique_function LocationChecker, -APISet ) - : Context(Context), API(API), -LocationChecker(std::move(LocationChecker)) {} +template +class ExtractAPIVisitorBase : public RecursiveASTVisitor { +protected: + ExtractAPIVisitorBase(ASTContext , APISet ) + : Context(Context), API(API) {} +public: const APISet () const { return API; } bool VisitVarDecl(const VarDecl *Decl); @@ -50,7 +53,11 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl); -private: + bool shouldDeclBeIncluded(const Decl *Decl) const; + + const RawComment *fetchRawCommentForDecl(const Decl *Decl) const; + +protected: /// Collect API information for the enum constants and associate with the /// parent enum. void recordEnumConstants(EnumRecord *EnumRecord, @@ -77,9 +84,582 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { void recordObjCProtocols(ObjCContainerRecord *Container, ObjCInterfaceDecl::protocol_range Protocols); + ASTContext APISet - llvm::unique_function LocationChecker; + + StringRef getTypedefName(const TagDecl *Decl) { +if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl()) + return TypedefDecl->getName(); + +return {}; + } + + bool isInSystemHeader(const Decl *D) { +return Context.getSourceManager().isInSystemHeader(D->getLocation()); + } + +private: + Derived () { +return *static_cast(this); + } +}; + +template +bool ExtractAPIVisitorBase::VisitVarDecl(const VarDecl *Decl) { + // skip function parameters. + if (isa(Decl)) +return true; + + // Skip non-global variables in records (struct/union/class). + if (Decl->getDeclContext()->isRecord()) +return true; + + // Skip local variables inside function or method. + if (!Decl->isDefinedOutsideFunctionOrMethod()) +return true; + + // If this is a template but not specialization or instantiation, skip. + if (Decl->getASTContext().getTemplateOrSpecializationInfo(Decl) && + Decl->getTemplateSpecializationKind() == TSK_Undeclared) +return true; + + if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) +return true; + + // Collect symbol information. + StringRef Name = Decl->getName(); + StringRef USR = API.recordUSR(Decl); + PresumedLoc Loc = + Context.getSourceManager().getPresumedLoc(Decl->getLocation()); + LinkageInfo Linkage = Decl->getLinkageAndVisibility(); + DocComment Comment; + if (auto *RawComment = + getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) +Comment = RawComment->getFormattedLines(Context.getSourceManager(), +Context.getDiagnostics()); + + // Build declaration fragments and sub-heading for the variable. + DeclarationFragments
[clang] 158a431 - Revert ExtractAPI from https://reviews.llvm.org/D146656
Author: Daniel Grumberg Date: 2023-03-27T22:12:36+01:00 New Revision: 158a431227a876306fe5838936413dd51588d0c6 URL: https://github.com/llvm/llvm-project/commit/158a431227a876306fe5838936413dd51588d0c6 DIFF: https://github.com/llvm/llvm-project/commit/158a431227a876306fe5838936413dd51588d0c6.diff LOG: Revert ExtractAPI from https://reviews.llvm.org/D146656 Added: clang/lib/ExtractAPI/ExtractAPIVisitor.cpp clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.h Modified: clang/include/clang/ExtractAPI/ExtractAPIVisitor.h clang/lib/ExtractAPI/CMakeLists.txt clang/lib/ExtractAPI/DeclarationFragments.cpp clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp clang/test/Index/extract-api-cursor.m clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CXExtractAPI.cpp Removed: clang/include/clang/ExtractAPI/TypedefUnderlyingTypeResolver.h diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index a31648b80195a..f6546fb4776a6 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -14,27 +14,24 @@ #ifndef LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H #define LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H -#include "llvm/ADT/FunctionExtras.h" - -#include "clang/AST/ASTContext.h" -#include "clang/AST/ParentMapContext.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceManager.h" #include "clang/ExtractAPI/API.h" -#include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" -#include +#include "llvm/ADT/FunctionExtras.h" namespace clang { namespace extractapi { -namespace impl { - -template -class ExtractAPIVisitorBase : public RecursiveASTVisitor { -protected: - ExtractAPIVisitorBase(ASTContext , APISet ) - : Context(Context), API(API) {} +/// The RecursiveASTVisitor to traverse symbol declarations and collect API +/// information. +class ExtractAPIVisitor : public RecursiveASTVisitor { public: + ExtractAPIVisitor(ASTContext , +llvm::unique_function LocationChecker, +APISet ) + : Context(Context), API(API), +LocationChecker(std::move(LocationChecker)) {} + const APISet () const { return API; } bool VisitVarDecl(const VarDecl *Decl); @@ -53,11 +50,7 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl); - bool shouldDeclBeIncluded(const Decl *Decl) const; - - const RawComment *fetchRawCommentForDecl(const Decl *Decl) const; - -protected: +private: /// Collect API information for the enum constants and associate with the /// parent enum. void recordEnumConstants(EnumRecord *EnumRecord, @@ -84,582 +77,9 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { void recordObjCProtocols(ObjCContainerRecord *Container, ObjCInterfaceDecl::protocol_range Protocols); - ASTContext APISet - - StringRef getTypedefName(const TagDecl *Decl) { -if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl()) - return TypedefDecl->getName(); - -return {}; - } - - bool isInSystemHeader(const Decl *D) { -return Context.getSourceManager().isInSystemHeader(D->getLocation()); - } - -private: - Derived () { -return *static_cast(this); - } -}; - -template -bool ExtractAPIVisitorBase::VisitVarDecl(const VarDecl *Decl) { - // skip function parameters. - if (isa(Decl)) -return true; - - // Skip non-global variables in records (struct/union/class). - if (Decl->getDeclContext()->isRecord()) -return true; - - // Skip local variables inside function or method. - if (!Decl->isDefinedOutsideFunctionOrMethod()) -return true; - - // If this is a template but not specialization or instantiation, skip. - if (Decl->getASTContext().getTemplateOrSpecializationInfo(Decl) && - Decl->getTemplateSpecializationKind() == TSK_Undeclared) -return true; - - if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) -return true; - - // Collect symbol information. - StringRef Name = Decl->getName(); - StringRef USR = API.recordUSR(Decl); - PresumedLoc Loc = - Context.getSourceManager().getPresumedLoc(Decl->getLocation()); - LinkageInfo Linkage = Decl->getLinkageAndVisibility(); - DocComment Comment; - if (auto *RawComment = - getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) -Comment = RawComment->getFormattedLines(Context.getSourceManager(), -Context.getDiagnostics()); - - // Build declaration fragments and sub-heading for the variable. - DeclarationFragments Declaration = - DeclarationFragmentsBuilder::getFragmentsForVar(Decl); - DeclarationFragments SubHeading = -
[clang] d0dd151 - Address code review feedback
Author: Daniel Grumberg Date: 2023-03-27T17:24:10+01:00 New Revision: d0dd151eed4bb9a6ea209790e2727c0a007f699a URL: https://github.com/llvm/llvm-project/commit/d0dd151eed4bb9a6ea209790e2727c0a007f699a DIFF: https://github.com/llvm/llvm-project/commit/d0dd151eed4bb9a6ea209790e2727c0a007f699a.diff LOG: Address code review feedback Added: Modified: clang/include/clang/ExtractAPI/ExtractAPIVisitor.h clang/lib/ExtractAPI/ExtractAPIConsumer.cpp Removed: diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index 31005787e1b2e..a31648b80195a 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -30,10 +30,11 @@ namespace impl { template class ExtractAPIVisitorBase : public RecursiveASTVisitor { -public: +protected: ExtractAPIVisitorBase(ASTContext , APISet ) : Context(Context), API(API) {} +public: const APISet () const { return API; } bool VisitVarDecl(const VarDecl *Decl); @@ -99,7 +100,9 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { } private: - Derived () { return *static_cast(this); } + Derived () { +return *static_cast(this); + } }; template @@ -121,7 +124,7 @@ bool ExtractAPIVisitorBase::VisitVarDecl(const VarDecl *Decl) { Decl->getTemplateSpecializationKind() == TSK_Undeclared) return true; - if (!getConcrete().shouldDeclBeIncluded(Decl)) + if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) return true; // Collect symbol information. @@ -131,7 +134,8 @@ bool ExtractAPIVisitorBase::VisitVarDecl(const VarDecl *Decl) { Context.getSourceManager().getPresumedLoc(Decl->getLocation()); LinkageInfo Linkage = Decl->getLinkageAndVisibility(); DocComment Comment; - if (auto *RawComment = getConcrete().fetchRawCommentForDecl(Decl)) + if (auto *RawComment = + getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) Comment = RawComment->getFormattedLines(Context.getSourceManager(), Context.getDiagnostics()); @@ -183,7 +187,7 @@ bool ExtractAPIVisitorBase::VisitFunctionDecl( return true; } - if (!getConcrete().shouldDeclBeIncluded(Decl)) + if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) return true; // Collect symbol information. @@ -193,7 +197,8 @@ bool ExtractAPIVisitorBase::VisitFunctionDecl( Context.getSourceManager().getPresumedLoc(Decl->getLocation()); LinkageInfo Linkage = Decl->getLinkageAndVisibility(); DocComment Comment; - if (auto *RawComment = getConcrete().fetchRawCommentForDecl(Decl)) + if (auto *RawComment = + getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) Comment = RawComment->getFormattedLines(Context.getSourceManager(), Context.getDiagnostics()); @@ -214,7 +219,7 @@ bool ExtractAPIVisitorBase::VisitFunctionDecl( template bool ExtractAPIVisitorBase::VisitEnumDecl(const EnumDecl *Decl) { - if (!getConcrete().shouldDeclBeIncluded(Decl)) + if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) return true; SmallString<128> QualifiedNameBuffer; @@ -232,7 +237,8 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const EnumDecl *Decl) { PresumedLoc Loc = Context.getSourceManager().getPresumedLoc(Decl->getLocation()); DocComment Comment; - if (auto *RawComment = getConcrete().fetchRawCommentForDecl(Decl)) + if (auto *RawComment = + getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) Comment = RawComment->getFormattedLines(Context.getSourceManager(), Context.getDiagnostics()); @@ -247,7 +253,8 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const EnumDecl *Decl) { Comment, Declaration, SubHeading, isInSystemHeader(Decl)); // Now collect information about the enumerators in this enum. - getConcrete().recordEnumConstants(EnumRecord, Decl->enumerators()); + getDerivedExtractAPIVisitor().recordEnumConstants(EnumRecord, +Decl->enumerators()); return true; } @@ -259,7 +266,7 @@ bool ExtractAPIVisitorBase::VisitRecordDecl(const RecordDecl *Decl) { if (isa(Decl)) return true; - if (!getConcrete().shouldDeclBeIncluded(Decl)) + if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) return true; // Collect symbol information. @@ -273,7 +280,8 @@ bool ExtractAPIVisitorBase::VisitRecordDecl(const RecordDecl *Decl) { PresumedLoc Loc = Context.getSourceManager().getPresumedLoc(Decl->getLocation()); DocComment Comment; - if (auto *RawComment = getConcrete().fetchRawCommentForDecl(Decl)) + if (auto *RawComment = +
[clang] ea35740 - [clang][ExtractAPI] Refactor ExtractAPIVisitor to make it more extensible
Author: Daniel Grumberg Date: 2023-03-27T17:24:10+01:00 New Revision: ea35740e7e189cdcdd88344ac60a53a5b8a8318d URL: https://github.com/llvm/llvm-project/commit/ea35740e7e189cdcdd88344ac60a53a5b8a8318d DIFF: https://github.com/llvm/llvm-project/commit/ea35740e7e189cdcdd88344ac60a53a5b8a8318d.diff LOG: [clang][ExtractAPI] Refactor ExtractAPIVisitor to make it more extensible Use CRTP to enable creating statically dispatched subclasses of ExtractAPIVisitor. This enables adding extension points and customising the behavior more easily. This is used in CXExtractAPI.cpp to create a specialized visitor for Libclang as well as streamlining the batch implementation in ExtractAPIConsumer.cpp Added: clang/include/clang/ExtractAPI/TypedefUnderlyingTypeResolver.h Modified: clang/include/clang/ExtractAPI/ExtractAPIVisitor.h clang/lib/ExtractAPI/CMakeLists.txt clang/lib/ExtractAPI/DeclarationFragments.cpp clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp clang/tools/libclang/CXExtractAPI.cpp Removed: clang/lib/ExtractAPI/ExtractAPIVisitor.cpp clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.h diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index f6546fb4776a6..31005787e1b2e 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -14,23 +14,25 @@ #ifndef LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H #define LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H +#include "llvm/ADT/FunctionExtras.h" + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ParentMapContext.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceManager.h" #include "clang/ExtractAPI/API.h" -#include "llvm/ADT/FunctionExtras.h" +#include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" +#include namespace clang { namespace extractapi { +namespace impl { -/// The RecursiveASTVisitor to traverse symbol declarations and collect API -/// information. -class ExtractAPIVisitor : public RecursiveASTVisitor { +template +class ExtractAPIVisitorBase : public RecursiveASTVisitor { public: - ExtractAPIVisitor(ASTContext , -llvm::unique_function LocationChecker, -APISet ) - : Context(Context), API(API), -LocationChecker(std::move(LocationChecker)) {} + ExtractAPIVisitorBase(ASTContext , APISet ) + : Context(Context), API(API) {} const APISet () const { return API; } @@ -50,7 +52,11 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl); -private: + bool shouldDeclBeIncluded(const Decl *Decl) const; + + const RawComment *fetchRawCommentForDecl(const Decl *Decl) const; + +protected: /// Collect API information for the enum constants and associate with the /// parent enum. void recordEnumConstants(EnumRecord *EnumRecord, @@ -77,9 +83,554 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { void recordObjCProtocols(ObjCContainerRecord *Container, ObjCInterfaceDecl::protocol_range Protocols); + ASTContext APISet - llvm::unique_function LocationChecker; + + StringRef getTypedefName(const TagDecl *Decl) { +if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl()) + return TypedefDecl->getName(); + +return {}; + } + + bool isInSystemHeader(const Decl *D) { +return Context.getSourceManager().isInSystemHeader(D->getLocation()); + } + +private: + Derived () { return *static_cast(this); } +}; + +template +bool ExtractAPIVisitorBase::VisitVarDecl(const VarDecl *Decl) { + // skip function parameters. + if (isa(Decl)) +return true; + + // Skip non-global variables in records (struct/union/class). + if (Decl->getDeclContext()->isRecord()) +return true; + + // Skip local variables inside function or method. + if (!Decl->isDefinedOutsideFunctionOrMethod()) +return true; + + // If this is a template but not specialization or instantiation, skip. + if (Decl->getASTContext().getTemplateOrSpecializationInfo(Decl) && + Decl->getTemplateSpecializationKind() == TSK_Undeclared) +return true; + + if (!getConcrete().shouldDeclBeIncluded(Decl)) +return true; + + // Collect symbol information. + StringRef Name = Decl->getName(); + StringRef USR = API.recordUSR(Decl); + PresumedLoc Loc = + Context.getSourceManager().getPresumedLoc(Decl->getLocation()); + LinkageInfo Linkage = Decl->getLinkageAndVisibility(); + DocComment Comment; + if (auto *RawComment = getConcrete().fetchRawCommentForDecl(Decl)) +Comment = RawComment->getFormattedLines(Context.getSourceManager(), +Context.getDiagnostics()); + + // Build declaration fragments and
[clang] 21750a1 - [clang][ExtractAPI] Refactor ExtractAPIVisitor to make it more extensible
Author: Daniel Grumberg Date: 2023-03-27T17:24:10+01:00 New Revision: 21750a1ae8c86ffefc72f115116c80a98a0792dc URL: https://github.com/llvm/llvm-project/commit/21750a1ae8c86ffefc72f115116c80a98a0792dc DIFF: https://github.com/llvm/llvm-project/commit/21750a1ae8c86ffefc72f115116c80a98a0792dc.diff LOG: [clang][ExtractAPI] Refactor ExtractAPIVisitor to make it more extensible Use CRTP to enable creating statically dispatched subclasses of ExtractAPIVisitor. This enables adding extension points and customising the behavior more easily. This is used in CXExtractAPI.cpp to create a specialized visitor for Libclang as well as streamlining the batch implementation in ExtractAPIConsumer.cpp [clang][ExtractAPI] Improve tests for clang_getSymbolGraphForCursor Adds a new mode to c-index-test that can fetch a single symbol symbol graph for a given source location. This way we can be more precise when writing tests for clang_getSymbolGraphForCursor. Additionaly this makes it easier to debug the function. Differential Revision: https://reviews.llvm.org/D146656 Added: Modified: clang/test/Index/extract-api-cursor.m clang/tools/c-index-test/c-index-test.c Removed: diff --git a/clang/test/Index/extract-api-cursor.m b/clang/test/Index/extract-api-cursor.m index 078f2f52e215c..16844ca1674ee 100644 --- a/clang/test/Index/extract-api-cursor.m +++ b/clang/test/Index/extract-api-cursor.m @@ -1,3 +1,5 @@ +// Test is line- and column-sensitive. Run lines are below + /// Foo docs struct Foo { /// Bar docs @@ -25,91 +27,94 @@ @interface Derived: Base - (void)derivedMethodWithValue:(id)value; @end -/// This won't show up in docs because we can't serialize it -@interface Derived () -/// Derived method in category docs, won't show up either. -- (void)derivedMethodInCategory; +@implementation Derived +- (void)derivedMethodWithValue:(id)value { +int a = 5; +} @end -// RUN: c-index-test -single-symbol-sgfs local %s | FileCheck %s - -// Checking for Foo -// CHECK: "parentContexts":[] -// CHECK-SAME: "relatedSymbols":[] -// CHECK-SAME: "relationships":[] -// CHECK-SAME: "text":"Foo docs" -// CHECK-SAME: "kind":{"displayName":"Structure","identifier":"objective-c.struct"} -// CHECK-SAME: "title":"Foo" - -// Checking for bar -// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.struct","name":"Foo","usr":"c:@S@Foo"}] -// CHECK-SAME: "relatedSymbols":[] -// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:@S@Foo@FI@bar","target":"c:@S@Foo" -// CHECK-SAME: "text":"Bar docs" -// CHECK-SAME: "kind":{"displayName":"Instance Property","identifier":"objective-c.property"} -// CHECK-SAME: "title":"bar" - -// Checking for Base -// CHECK-NEXT: "parentContexts":[] -// CHECK-SAME: "relatedSymbols":[] -// CHECK-SAME: "relationships":[] -// CHECK-SAME: "text":"Base docs" -// CHECK-SAME: "kind":{"displayName":"Class","identifier":"objective-c.class"} -// CHECK-SAME: "title":"Base" - -// Checking for baseProperty -// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}] -// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" -// CHECK-SAME: "isSystem":false -// CHECK-SAME: "usr":"c:@S@Foo"}] -// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(py)baseProperty","target":"c:objc(cs)Base" -// CHECK-SAME: "text":"Base property docs" -// CHECK-SAME: "kind":{"displayName":"Instance Property","identifier":"objective-c.property"} -// CHECK-SAME: "title":"baseProperty" - -// Checking for baseMethodWithArg -// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}] -// CHECK-SAME: "relatedSymbols":[] -// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(im)baseMethodWithArg:","target":"c:objc(cs)Base" -// CHECK-SAME: "text":"Base method docs" -// CHECK-SAME: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"} -// CHECK-SAME: "title":"baseMethodWithArg:" - -// Checking for Protocol -// CHECK-NEXT: "parentContexts":[] -// CHECK-SAME: "relatedSymbols":[] -// CHECK-SAME: "relationships":[] -// CHECK-SAME: "text":"Protocol docs" -// CHECK-SAME: "kind":{"displayName":"Protocol","identifier":"objective-c.protocol"} -// CHECK-SAME: "title":"Protocol" - -// Checking for protocolProperty -// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.protocol","name":"Protocol","usr":"c:objc(pl)Protocol"}] -// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" -// CHECK-SAME: "isSystem":false -// CHECK-SAME: "usr":"c:@S@Foo"}] -// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(pl)Protocol(py)protocolProperty","target":"c:objc(pl)Protocol" -// CHECK-SAME: "text":"Protocol property docs" -// CHECK-SAME: "kind":{"displayName":"Instance Property","identifier":"objective-c.property"}
[clang] afce10c - [clang][ExtractAPI] Add semicolons for enum, typedef, struct declaration fragments
Author: NagaChaitanya Vellanki Date: 2023-03-20T15:43:00Z New Revision: afce10c5b60fada1db369d3770f4389da7ef30ef URL: https://github.com/llvm/llvm-project/commit/afce10c5b60fada1db369d3770f4389da7ef30ef DIFF: https://github.com/llvm/llvm-project/commit/afce10c5b60fada1db369d3770f4389da7ef30ef.diff LOG: [clang][ExtractAPI] Add semicolons for enum, typedef, struct declaration fragments Fixes https://github.com/llvm/llvm-project/issues/61480 Reviewed By: dang Differential Revision: https://reviews.llvm.org/D146354 Added: Modified: clang/lib/ExtractAPI/DeclarationFragments.cpp clang/test/ExtractAPI/anonymous_record_no_typedef.c clang/test/ExtractAPI/enum.c clang/test/ExtractAPI/struct.c clang/test/ExtractAPI/typedef.c clang/test/ExtractAPI/typedef_anonymous_record.c clang/test/ExtractAPI/typedef_chain.c clang/test/ExtractAPI/underscored.c Removed: diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 12c91c582aa98..b8de1270b5f02 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -470,7 +470,7 @@ DeclarationFragmentsBuilder::getFragmentsForEnum(const EnumDecl *EnumDecl) { getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After)) .append(std::move(After)); - return Fragments; + return Fragments.append(";", DeclarationFragments::FragmentKind::Text); } DeclarationFragments @@ -493,7 +493,8 @@ DeclarationFragmentsBuilder::getFragmentsForStruct(const RecordDecl *Record) { if (!Record->getName().empty()) Fragments.appendSpace().append( Record->getName(), DeclarationFragments::FragmentKind::Identifier); - return Fragments; + + return Fragments.append(";", DeclarationFragments::FragmentKind::Text); } DeclarationFragments @@ -743,7 +744,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef( .appendSpace() .append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier); - return Fragments; + return Fragments.append(";", DeclarationFragments::FragmentKind::Text); } template diff --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c b/clang/test/ExtractAPI/anonymous_record_no_typedef.c index abb96db058dbf..880a42c30ceb8 100644 --- a/clang/test/ExtractAPI/anonymous_record_no_typedef.c +++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c @@ -94,6 +94,10 @@ struct Vehicle { "kind": "typeIdentifier", "preciseIdentifier": "c:i", "spelling": "unsigned int" +}, +{ + "kind": "text", + "spelling": ";" } ], "docComment": { @@ -241,6 +245,10 @@ struct Vehicle { { "kind": "identifier", "spelling": "Vehicle" +}, +{ + "kind": "text", + "spelling": ";" } ], "docComment": { diff --git a/clang/test/ExtractAPI/enum.c b/clang/test/ExtractAPI/enum.c index 7b345464cb982..a6c749028bd17 100644 --- a/clang/test/ExtractAPI/enum.c +++ b/clang/test/ExtractAPI/enum.c @@ -153,6 +153,10 @@ enum { "kind": "typeIdentifier", "preciseIdentifier": "c:i", "spelling": "unsigned int" +}, +{ + "kind": "text", + "spelling": ";" } ], "docComment": { @@ -461,6 +465,10 @@ enum { "kind": "typeIdentifier", "preciseIdentifier": "c:c", "spelling": "unsigned char" +}, +{ + "kind": "text", + "spelling": ";" } ], "identifier": { @@ -684,6 +692,10 @@ enum { "kind": "typeIdentifier", "preciseIdentifier": "c:i", "spelling": "unsigned int" +}, +{ + "kind": "text", + "spelling": ";" } ], "identifier": { @@ -772,6 +784,10 @@ enum { "kind": "typeIdentifier", "preciseIdentifier": "c:i", "spelling": "unsigned int" +}, +{ + "kind": "text", + "spelling": ";" } ], "identifier": { diff --git a/clang/test/ExtractAPI/struct.c b/clang/test/ExtractAPI/struct.c index 7e93f0d7e7bfa..cd6d25d835821 100644 --- a/clang/test/ExtractAPI/struct.c +++ b/clang/test/ExtractAPI/struct.c @@ -89,6 +89,10 @@ struct Color { { "kind": "identifier", "spelling": "Color" +}, +{ + "kind": "text", + "spelling": ";" } ], "docComment": { diff --git a/clang/test/ExtractAPI/typedef.c b/clang/test/ExtractAPI/typedef.c index fb9b8ef32cdc1..89df9db8b362d 100644 --- a/clang/test/ExtractAPI/typedef.c +++ b/clang/test/ExtractAPI/typedef.c @@ -66,6 +66,10 @@ typedef int MyInt; { "kind":
[clang] 65f7a84 - [clang][ExtractAPI] Handle platform specific unavailability correctly
Author: Ankur Date: 2023-03-02T15:49:46Z New Revision: 65f7a84cf38b9839de0f29877d5ba4895848ea73 URL: https://github.com/llvm/llvm-project/commit/65f7a84cf38b9839de0f29877d5ba4895848ea73 DIFF: https://github.com/llvm/llvm-project/commit/65f7a84cf38b9839de0f29877d5ba4895848ea73.diff LOG: [clang][ExtractAPI] Handle platform specific unavailability correctly This Patch gives ExtractAPI the ability to emit correct availability information for symbols marked as unavailable on a specific platform ( PR#60954 ) Reviewed By: dang Differential Revision: https://reviews.llvm.org/D144940 Added: Modified: clang/include/clang/ExtractAPI/AvailabilityInfo.h clang/lib/ExtractAPI/AvailabilityInfo.cpp clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/test/ExtractAPI/availability.c Removed: diff --git a/clang/include/clang/ExtractAPI/AvailabilityInfo.h b/clang/include/clang/ExtractAPI/AvailabilityInfo.h index a258bc52c125d..0af373135b667 100644 --- a/clang/include/clang/ExtractAPI/AvailabilityInfo.h +++ b/clang/include/clang/ExtractAPI/AvailabilityInfo.h @@ -33,12 +33,14 @@ struct AvailabilityInfo { VersionTuple Introduced; VersionTuple Deprecated; VersionTuple Obsoleted; + bool Unavailable; AvailabilityInfo() = default; AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D, - VersionTuple O) - : Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O) {} + VersionTuple O, bool U) + : Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O), +Unavailable(U) {} }; class AvailabilitySet { diff --git a/clang/lib/ExtractAPI/AvailabilityInfo.cpp b/clang/lib/ExtractAPI/AvailabilityInfo.cpp index ada64cfb92e64..1df852fdbf930 100644 --- a/clang/lib/ExtractAPI/AvailabilityInfo.cpp +++ b/clang/lib/ExtractAPI/AvailabilityInfo.cpp @@ -42,8 +42,8 @@ AvailabilitySet::AvailabilitySet(const Decl *Decl) { Availability->Obsoleted = Attr->getObsoleted(); } else { Availabilities.emplace_back(Domain, Attr->getIntroduced(), -Attr->getDeprecated(), -Attr->getObsoleted()); +Attr->getDeprecated(), Attr->getObsoleted(), +Attr->getUnavailable()); } } } diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 8beb01697bc2e..8a98f5cf0c71f 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -171,12 +171,16 @@ serializeAvailability(const AvailabilitySet ) { for (const auto : Availabilities) { Object Availability; Availability["domain"] = AvailInfo.Domain; -serializeObject(Availability, "introducedVersion", -serializeSemanticVersion(AvailInfo.Introduced)); -serializeObject(Availability, "deprecatedVersion", -serializeSemanticVersion(AvailInfo.Deprecated)); -serializeObject(Availability, "obsoletedVersion", -serializeSemanticVersion(AvailInfo.Obsoleted)); +if (AvailInfo.Unavailable) + Availability["isUnconditionallyUnavailable"] = true; +else { + serializeObject(Availability, "introducedVersion", + serializeSemanticVersion(AvailInfo.Introduced)); + serializeObject(Availability, "deprecatedVersion", + serializeSemanticVersion(AvailInfo.Deprecated)); + serializeObject(Availability, "obsoletedVersion", + serializeSemanticVersion(AvailInfo.Obsoleted)); +} AvailabilityArray.emplace_back(std::move(Availability)); } diff --git a/clang/test/ExtractAPI/availability.c b/clang/test/ExtractAPI/availability.c index 54dbf5a6cac95..7d071909a092e 100644 --- a/clang/test/ExtractAPI/availability.c +++ b/clang/test/ExtractAPI/availability.c @@ -26,6 +26,9 @@ void e(void) __attribute__((deprecated)) __attribute__((availability(macos, intr void f(void) __attribute__((unavailable)) __attribute__((availability(macos, introduced=11.0))); void d(void) __attribute__((availability(tvos, introduced=15.0))); + +void e(void) __attribute__((availability(tvos, unavailable))); + ///expected-no-diagnostics //--- reference.output.json.in @@ -391,6 +394,10 @@ void d(void) __attribute__((availability(tvos, introduced=15.0))); "minor": 0, "patch": 0 } +}, +{ + "domain": "tvos", + "isUnconditionallyUnavailable": true } ], "declarationFragments": [ ___ cfe-commits mailing list cfe-commits@lists.llvm.org
[clang] 7da2d64 - [clang] [extract-api] Don't crash for category in libclang APIs
Author: Daniel Grumberg Date: 2023-02-10T16:30:19Z New Revision: 7da2d644e0398be39e188ea6eacab2a942e0fa7e URL: https://github.com/llvm/llvm-project/commit/7da2d644e0398be39e188ea6eacab2a942e0fa7e DIFF: https://github.com/llvm/llvm-project/commit/7da2d644e0398be39e188ea6eacab2a942e0fa7e.diff LOG: [clang] [extract-api] Don't crash for category in libclang APIs Remove failure conditions for categories in libclang and return empty content instead. Differential Revision: https://reviews.llvm.org/D142101 Added: Modified: clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/test/Index/extract-api-cursor.m Removed: diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 01e9b37d26802..8beb01697bc2e 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -487,6 +487,7 @@ bool generatePathComponents( SmallVector ReverseComponenents; ReverseComponenents.emplace_back(Record.USR, Record.Name, Record.getKind()); const auto *CurrentParent = + bool FailedToFindParent = false; while (CurrentParent && !CurrentParent->empty()) { PathComponent CurrentParentComponent(CurrentParent->ParentUSR, CurrentParent->ParentName, @@ -509,8 +510,10 @@ bool generatePathComponents( // The parent record doesn't exist which means the symbol shouldn't be // treated as part of the current product. -if (!ParentRecord) - return true; +if (!ParentRecord) { + FailedToFindParent = true; + break; +} ReverseComponenents.push_back(std::move(CurrentParentComponent)); CurrentParent = >ParentInformation; @@ -519,8 +522,9 @@ bool generatePathComponents( for (const auto : reverse(ReverseComponenents)) ComponentTransformer(PC); - return false; + return FailedToFindParent; } + Object serializeParentContext(const PathComponent , Language Lang) { Object ParentContextElem; ParentContextElem["usr"] = PC.USR; @@ -533,12 +537,15 @@ template Array generateParentContexts(const RecordTy , const APISet , Language Lang) { Array ParentContexts; - if (generatePathComponents( - Record, API, [Lang, ](const PathComponent ) { -ParentContexts.push_back(serializeParentContext(PC, Lang)); - })) -ParentContexts.clear(); - ParentContexts.pop_back(); + generatePathComponents(Record, API, + [Lang, ](const PathComponent ) { + ParentContexts.push_back( + serializeParentContext(PC, Lang)); + }); + + // The last component would be the record itself so let's remove it. + if (!ParentContexts.empty()) +ParentContexts.pop_back(); return ParentContexts; } @@ -865,6 +872,9 @@ SymbolGraphSerializer::serializeSingleSymbolSGF(StringRef USR, if (!Record) return {}; + if (isa(Record)) +return {}; + Object Root; APIIgnoresList EmptyIgnores; SymbolGraphSerializer Serializer(API, EmptyIgnores, diff --git a/clang/test/Index/extract-api-cursor.m b/clang/test/Index/extract-api-cursor.m index a462c115826c1..078f2f52e215c 100644 --- a/clang/test/Index/extract-api-cursor.m +++ b/clang/test/Index/extract-api-cursor.m @@ -25,6 +25,12 @@ @interface Derived: Base - (void)derivedMethodWithValue:(id)value; @end +/// This won't show up in docs because we can't serialize it +@interface Derived () +/// Derived method in category docs, won't show up either. +- (void)derivedMethodInCategory; +@end + // RUN: c-index-test -single-symbol-sgfs local %s | FileCheck %s // Checking for Foo @@ -53,7 +59,7 @@ - (void)derivedMethodWithValue:(id)value; // Checking for baseProperty // CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}] -// CHECK-SAME:"relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" +// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" // CHECK-SAME: "isSystem":false // CHECK-SAME: "usr":"c:@S@Foo"}] // CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(py)baseProperty","target":"c:objc(cs)Base" @@ -63,7 +69,7 @@ - (void)derivedMethodWithValue:(id)value; // Checking for baseMethodWithArg // CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}] -// CHECK-SAME:"relatedSymbols":[] +// CHECK-SAME: "relatedSymbols":[] // CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(im)baseMethodWithArg:","target":"c:objc(cs)Base" // CHECK-SAME: "text":"Base method docs" // CHECK-SAME: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"} @@
[clang] 8dcb629 - [clang][ExtractAPI] Fix naming of typedef'd anonymous enums
Author: Daniel Grumberg Date: 2022-12-16T11:01:03Z New Revision: 8dcb629aa4ccfdd18fb700cabb45fd74fcd291c8 URL: https://github.com/llvm/llvm-project/commit/8dcb629aa4ccfdd18fb700cabb45fd74fcd291c8 DIFF: https://github.com/llvm/llvm-project/commit/8dcb629aa4ccfdd18fb700cabb45fd74fcd291c8.diff LOG: [clang][ExtractAPI] Fix naming of typedef'd anonymous enums Anonymous enums that are typedef'd should take on the name of the typedef. Differential Revision: https://reviews.llvm.org/D140010 Added: Modified: clang/lib/ExtractAPI/ExtractAPIVisitor.cpp clang/test/ExtractAPI/typedef_anonymous_record.c Removed: diff --git a/clang/lib/ExtractAPI/ExtractAPIVisitor.cpp b/clang/lib/ExtractAPI/ExtractAPIVisitor.cpp index 38d95aaa6d5eb..24260cf89383d 100644 --- a/clang/lib/ExtractAPI/ExtractAPIVisitor.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIVisitor.cpp @@ -29,6 +29,7 @@ #include "clang/ExtractAPI/DeclarationFragments.h" #include "clang/Frontend/ASTConsumers.h" #include "clang/Frontend/FrontendOptions.h" +#include "llvm/Support/raw_ostream.h" using namespace clang; using namespace extractapi; @@ -167,11 +168,16 @@ bool ExtractAPIVisitor::VisitEnumDecl(const EnumDecl *Decl) { if (!LocationChecker(Decl->getLocation())) return true; + SmallString<128> QualifiedNameBuffer; // Collect symbol information. - std::string NameString = Decl->getQualifiedNameAsString(); - StringRef Name(NameString); + StringRef Name = Decl->getName(); if (Name.empty()) Name = getTypedefName(Decl); + if (Name.empty()) { +llvm::raw_svector_ostream OS(QualifiedNameBuffer); +Decl->printQualifiedName(OS); +Name = QualifiedNameBuffer.str(); + } StringRef USR = API.recordUSR(Decl); PresumedLoc Loc = diff --git a/clang/test/ExtractAPI/typedef_anonymous_record.c b/clang/test/ExtractAPI/typedef_anonymous_record.c index e3e34769321f1..1bd93b92ede81 100644 --- a/clang/test/ExtractAPI/typedef_anonymous_record.c +++ b/clang/test/ExtractAPI/typedef_anonymous_record.c @@ -2,21 +2,22 @@ // RUN: split-file %s %t // RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \ // RUN: %t/reference.output.json.in >> %t/reference.output.json -// RUN: %clang -extract-api --product-name=TypedefChain -target arm64-apple-macosx \ -// RUN: -x objective-c-header %t/input.h -o %t/output.json | FileCheck -allow-empty %s +// RUN: %clang_cc1 -extract-api --product-name=TypedefChain -triple arm64-apple-macosx \ +// RUN: -x c-header %t/input.h -o %t/output.json -verify // Generator version is not consistent across test runs, normalize it. // RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ // RUN: %t/output.json >> %t/output-normalized.json // RUN: diff %t/reference.output.json %t/output-normalized.json -// CHECK-NOT: error: -// CHECK-NOT: warning: - //--- input.h typedef struct { } MyStruct; typedef MyStruct MyStructStruct; typedef MyStructStruct MyStructStructStruct; +typedef enum { Case } MyEnum; +typedef MyEnum MyEnumEnum; +typedef MyEnumEnum MyEnumEnumEnum; +// expected-no-diagnostics //--- reference.output.json.in { @@ -43,8 +44,110 @@ typedef MyStructStruct MyStructStructStruct; "vendor": "apple" } }, - "relationships": [], + "relationships": [ +{ + "kind": "memberOf", + "source": "c:@EA@MyEnum@Case", + "target": "c:@EA@MyEnum", + "targetFallback": "MyEnum" +} + ], "symbols": [ +{ + "accessLevel": "public", + "declarationFragments": [ +{ + "kind": "keyword", + "spelling": "typedef" +}, +{ + "kind": "text", + "spelling": " " +}, +{ + "kind": "keyword", + "spelling": "enum" +}, +{ + "kind": "text", + "spelling": " " +}, +{ + "kind": "identifier", + "spelling": "MyEnum" +} + ], + "identifier": { +"interfaceLanguage": "c", +"precise": "c:@EA@MyEnum" + }, + "kind": { +"displayName": "Enumeration", +"identifier": "c.enum" + }, + "location": { +"position": { + "character": 9, + "line": 4 +}, +"uri": "file://INPUT_DIR/input.h" + }, + "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "MyEnum" + } +], +"title": "MyEnum" + }, + "pathComponents": [ +"MyEnum" + ] +}, +{ + "accessLevel": "public", + "declarationFragments": [ +{ + "kind": "identifier", + "spelling": "Case" +} + ], + "identifier": { +"interfaceLanguage": "c", +"precise": "c:@EA@MyEnum@Case" + }, + "kind": { +"displayName": "Enumeration Case", +"identifier": "c.enum.case" +
[clang] 39dbfa7 - Revert "Only add targetFallback if target is not in defined in current product"
Author: Daniel Grumberg Date: 2022-11-07T13:33:59Z New Revision: 39dbfa72aaebe64e913d65f1eeab48c5f33b8010 URL: https://github.com/llvm/llvm-project/commit/39dbfa72aaebe64e913d65f1eeab48c5f33b8010 DIFF: https://github.com/llvm/llvm-project/commit/39dbfa72aaebe64e913d65f1eeab48c5f33b8010.diff LOG: Revert "Only add targetFallback if target is not in defined in current product" This was an accidental addition of a non-reviewed change. This reverts commit f63db91590db98e13cb4440fdaa5c40e219b. Added: Modified: clang/include/clang/ExtractAPI/API.h clang/lib/ExtractAPI/API.cpp clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/test/ExtractAPI/anonymous_record_no_typedef.c clang/test/ExtractAPI/enum.c clang/test/ExtractAPI/objc_category.m clang/test/ExtractAPI/objc_interface.m clang/test/ExtractAPI/objc_property.m clang/test/ExtractAPI/objc_protocol.m clang/test/ExtractAPI/struct.c clang/test/ExtractAPI/underscored.c Removed: diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index ffb700eb923f..b77d76d500df 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -675,12 +675,6 @@ class APISet { const RecordMap () const { return Macros; } const RecordMap () const { return Typedefs; } - /// Get the APIRecord associated with the USR if it's defined in the - /// current product. - /// - /// \returns a APIRecord pointer to the stored symbol record if it exists. - APIRecord *getSymbolForUSR(StringRef USR) const; - /// Generate and store the USR of declaration \p D. /// /// Note: The USR string is stored in and owned by Allocator. diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp index 48322023d504..8ab03a833e3c 100644 --- a/clang/lib/ExtractAPI/API.cpp +++ b/clang/lib/ExtractAPI/API.cpp @@ -197,39 +197,6 @@ TypedefRecord *APISet::addTypedef(StringRef Name, StringRef USR, Comment, Declaration, SubHeading, UnderlyingType); } -template -static APIRecord *getSymbolInRecordMapForUSR(StringRef USR, - const RecordMap ) { - auto It = Records.find(USR); - return (It != Records.end() ? It->second.get() : nullptr); -} - -APIRecord *APISet::getSymbolForUSR(StringRef USR) const { - if (USR.empty()) -return nullptr; - if (auto *Record = getSymbolInRecordMapForUSR(USR, ObjCProtocols)) -return Record; - if (auto *Record = getSymbolInRecordMapForUSR(USR, ObjCInterfaces)) -return Record; - if (auto *Record = getSymbolInRecordMapForUSR(USR, ObjCCategories)) -return Record; - if (auto *Record = getSymbolInRecordMapForUSR(USR, ObjCCategories)) -return Record; - if (auto *Record = getSymbolInRecordMapForUSR(USR, Structs)) -return Record; - if (auto *Record = getSymbolInRecordMapForUSR(USR, Enums)) -return Record; - if (auto *Record = getSymbolInRecordMapForUSR(USR, Typedefs)) -return Record; - if (auto *Record = getSymbolInRecordMapForUSR(USR, GlobalFunctions)) -return Record; - if (auto *Record = getSymbolInRecordMapForUSR(USR, GlobalVariables)) -return Record; - if (auto *Record = getSymbolInRecordMapForUSR(USR, Macros)) -return Record; - return nullptr; -} - StringRef APISet::recordUSR(const Decl *D) { SmallString<128> USR; index::generateUSRForDecl(D, USR); diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 807c618e3198..641f1ae812a5 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -559,10 +559,7 @@ void SymbolGraphSerializer::serializeRelationship(RelationshipKind Kind, Object Relationship; Relationship["source"] = Source.USR; Relationship["target"] = Target.USR; - // Emit a fallback if the target is not a symbol that will be part of this - // symbol graph. - if (API.getSymbolForUSR(Target.USR) == nullptr) -Relationship["targetFallback"] = Target.Name; + Relationship["targetFallback"] = Target.Name; Relationship["kind"] = getRelationshipString(Kind); Relationships.emplace_back(std::move(Relationship)); diff --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c b/clang/test/ExtractAPI/anonymous_record_no_typedef.c index e20abfdd86ab..abb96db058db 100644 --- a/clang/test/ExtractAPI/anonymous_record_no_typedef.c +++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c @@ -56,22 +56,26 @@ struct Vehicle { { "kind": "memberOf", "source": "c:@S@Vehicle@E@input.h@64@Bicycle", - "target": "c:@S@Vehicle@E@input.h@64" + "target": "c:@S@Vehicle@E@input.h@64", + "targetFallback": "Vehicle::enum (unnamed)" }, { "kind": "memberOf",
[clang] 671709f - [clang][ExtractAPI] Add targetFallback to relationships in symbol graph
Author: Daniel Grumberg Date: 2022-11-07T13:12:34Z New Revision: 671709f0e7d49826fd0908be2c9aed07debf5bc9 URL: https://github.com/llvm/llvm-project/commit/671709f0e7d49826fd0908be2c9aed07debf5bc9 DIFF: https://github.com/llvm/llvm-project/commit/671709f0e7d49826fd0908be2c9aed07debf5bc9.diff LOG: [clang][ExtractAPI] Add targetFallback to relationships in symbol graph Adds a 'targetFallback' field to relationships in symbol graph that contains the plain name of the relationship target. This is useful for clients when the relationship target symbol is not available. Differential Revision: https://reviews.llvm.org/D136455 Added: Modified: clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/test/ExtractAPI/anonymous_record_no_typedef.c clang/test/ExtractAPI/enum.c clang/test/ExtractAPI/objc_category.m clang/test/ExtractAPI/objc_interface.m clang/test/ExtractAPI/objc_property.m clang/test/ExtractAPI/objc_protocol.m clang/test/ExtractAPI/struct.c clang/test/ExtractAPI/underscored.c Removed: diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 988ecd2defa9c..641f1ae812a58 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -559,6 +559,7 @@ void SymbolGraphSerializer::serializeRelationship(RelationshipKind Kind, Object Relationship; Relationship["source"] = Source.USR; Relationship["target"] = Target.USR; + Relationship["targetFallback"] = Target.Name; Relationship["kind"] = getRelationshipString(Kind); Relationships.emplace_back(std::move(Relationship)); diff --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c b/clang/test/ExtractAPI/anonymous_record_no_typedef.c index e20abfdd86ab4..abb96db058dbf 100644 --- a/clang/test/ExtractAPI/anonymous_record_no_typedef.c +++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c @@ -56,22 +56,26 @@ struct Vehicle { { "kind": "memberOf", "source": "c:@S@Vehicle@E@input.h@64@Bicycle", - "target": "c:@S@Vehicle@E@input.h@64" + "target": "c:@S@Vehicle@E@input.h@64", + "targetFallback": "Vehicle::enum (unnamed)" }, { "kind": "memberOf", "source": "c:@S@Vehicle@E@input.h@64@Car", - "target": "c:@S@Vehicle@E@input.h@64" + "target": "c:@S@Vehicle@E@input.h@64", + "targetFallback": "Vehicle::enum (unnamed)" }, { "kind": "memberOf", "source": "c:@S@Vehicle@FI@type", - "target": "c:@S@Vehicle" + "target": "c:@S@Vehicle", + "targetFallback": "Vehicle" }, { "kind": "memberOf", "source": "c:@S@Vehicle@FI@information", - "target": "c:@S@Vehicle" + "target": "c:@S@Vehicle", + "targetFallback": "Vehicle" } ], "symbols": [ diff --git a/clang/test/ExtractAPI/enum.c b/clang/test/ExtractAPI/enum.c index 07d848082981f..7b345464cb982 100644 --- a/clang/test/ExtractAPI/enum.c +++ b/clang/test/ExtractAPI/enum.c @@ -65,57 +65,68 @@ enum { { "kind": "memberOf", "source": "c:@E@Vehicle@Bicycle", - "target": "c:@E@Vehicle" + "target": "c:@E@Vehicle", + "targetFallback": "Vehicle" }, { "kind": "memberOf", "source": "c:@E@Vehicle@Car", - "target": "c:@E@Vehicle" + "target": "c:@E@Vehicle", + "targetFallback": "Vehicle" }, { "kind": "memberOf", "source": "c:@E@Vehicle@Train", - "target": "c:@E@Vehicle" + "target": "c:@E@Vehicle", + "targetFallback": "Vehicle" }, { "kind": "memberOf", "source": "c:@E@Vehicle@Ship", - "target": "c:@E@Vehicle" + "target": "c:@E@Vehicle", + "targetFallback": "Vehicle" }, { "kind": "memberOf", "source": "c:@E@Vehicle@Airplane", - "target": "c:@E@Vehicle" + "target": "c:@E@Vehicle", + "targetFallback": "Vehicle" }, { "kind": "memberOf", "source": "c:@E@Direction@North", - "target": "c:@E@Direction" + "target": "c:@E@Direction", + "targetFallback": "Direction" }, { "kind": "memberOf", "source": "c:@E@Direction@East", - "target": "c:@E@Direction" + "target": "c:@E@Direction", + "targetFallback": "Direction" }, { "kind": "memberOf", "source": "c:@E@Direction@South", - "target": "c:@E@Direction" + "target": "c:@E@Direction", + "targetFallback": "Direction" }, { "kind": "memberOf", "source": "c:@E@Direction@West", - "target": "c:@E@Direction" + "target": "c:@E@Direction", + "targetFallback": "Direction" }, { "kind": "memberOf", "source": "c:@Ea@Constant@Constant", - "target":
[clang] f63db91 - Only add targetFallback if target is not in defined in current product
Author: Daniel Grumberg Date: 2022-11-07T13:12:34Z New Revision: f63db91590db98e13cb4440fdaa5c40e219b URL: https://github.com/llvm/llvm-project/commit/f63db91590db98e13cb4440fdaa5c40e219b DIFF: https://github.com/llvm/llvm-project/commit/f63db91590db98e13cb4440fdaa5c40e219b.diff LOG: Only add targetFallback if target is not in defined in current product Added: Modified: clang/include/clang/ExtractAPI/API.h clang/lib/ExtractAPI/API.cpp clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/test/ExtractAPI/anonymous_record_no_typedef.c clang/test/ExtractAPI/enum.c clang/test/ExtractAPI/objc_category.m clang/test/ExtractAPI/objc_interface.m clang/test/ExtractAPI/objc_property.m clang/test/ExtractAPI/objc_protocol.m clang/test/ExtractAPI/struct.c clang/test/ExtractAPI/underscored.c Removed: diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index b77d76d500df6..ffb700eb923f8 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -675,6 +675,12 @@ class APISet { const RecordMap () const { return Macros; } const RecordMap () const { return Typedefs; } + /// Get the APIRecord associated with the USR if it's defined in the + /// current product. + /// + /// \returns a APIRecord pointer to the stored symbol record if it exists. + APIRecord *getSymbolForUSR(StringRef USR) const; + /// Generate and store the USR of declaration \p D. /// /// Note: The USR string is stored in and owned by Allocator. diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp index 8ab03a833e3c2..48322023d5041 100644 --- a/clang/lib/ExtractAPI/API.cpp +++ b/clang/lib/ExtractAPI/API.cpp @@ -197,6 +197,39 @@ TypedefRecord *APISet::addTypedef(StringRef Name, StringRef USR, Comment, Declaration, SubHeading, UnderlyingType); } +template +static APIRecord *getSymbolInRecordMapForUSR(StringRef USR, + const RecordMap ) { + auto It = Records.find(USR); + return (It != Records.end() ? It->second.get() : nullptr); +} + +APIRecord *APISet::getSymbolForUSR(StringRef USR) const { + if (USR.empty()) +return nullptr; + if (auto *Record = getSymbolInRecordMapForUSR(USR, ObjCProtocols)) +return Record; + if (auto *Record = getSymbolInRecordMapForUSR(USR, ObjCInterfaces)) +return Record; + if (auto *Record = getSymbolInRecordMapForUSR(USR, ObjCCategories)) +return Record; + if (auto *Record = getSymbolInRecordMapForUSR(USR, ObjCCategories)) +return Record; + if (auto *Record = getSymbolInRecordMapForUSR(USR, Structs)) +return Record; + if (auto *Record = getSymbolInRecordMapForUSR(USR, Enums)) +return Record; + if (auto *Record = getSymbolInRecordMapForUSR(USR, Typedefs)) +return Record; + if (auto *Record = getSymbolInRecordMapForUSR(USR, GlobalFunctions)) +return Record; + if (auto *Record = getSymbolInRecordMapForUSR(USR, GlobalVariables)) +return Record; + if (auto *Record = getSymbolInRecordMapForUSR(USR, Macros)) +return Record; + return nullptr; +} + StringRef APISet::recordUSR(const Decl *D) { SmallString<128> USR; index::generateUSRForDecl(D, USR); diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 641f1ae812a58..807c618e3198f 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -559,7 +559,10 @@ void SymbolGraphSerializer::serializeRelationship(RelationshipKind Kind, Object Relationship; Relationship["source"] = Source.USR; Relationship["target"] = Target.USR; - Relationship["targetFallback"] = Target.Name; + // Emit a fallback if the target is not a symbol that will be part of this + // symbol graph. + if (API.getSymbolForUSR(Target.USR) == nullptr) +Relationship["targetFallback"] = Target.Name; Relationship["kind"] = getRelationshipString(Kind); Relationships.emplace_back(std::move(Relationship)); diff --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c b/clang/test/ExtractAPI/anonymous_record_no_typedef.c index abb96db058dbf..e20abfdd86ab4 100644 --- a/clang/test/ExtractAPI/anonymous_record_no_typedef.c +++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c @@ -56,26 +56,22 @@ struct Vehicle { { "kind": "memberOf", "source": "c:@S@Vehicle@E@input.h@64@Bicycle", - "target": "c:@S@Vehicle@E@input.h@64", - "targetFallback": "Vehicle::enum (unnamed)" + "target": "c:@S@Vehicle@E@input.h@64" }, { "kind": "memberOf", "source": "c:@S@Vehicle@E@input.h@64@Car", - "target": "c:@S@Vehicle@E@input.h@64", - "targetFallback": "Vehicle::enum
[clang] 791fe26 - [clang][ExtractAPI] Allow users to specify a list of symbols to ignore
Author: Daniel Grumberg Date: 2022-10-25T11:46:04+01:00 New Revision: 791fe26d758173e569d26d831b36ee8527e1a766 URL: https://github.com/llvm/llvm-project/commit/791fe26d758173e569d26d831b36ee8527e1a766 DIFF: https://github.com/llvm/llvm-project/commit/791fe26d758173e569d26d831b36ee8527e1a766.diff LOG: [clang][ExtractAPI] Allow users to specify a list of symbols to ignore Adds a `--extract-api-ignores=` command line option that allows users to provide a file containing a new line separated list of symbols to unconditionally ignore when extracting API information. Differential Revision: https://reviews.llvm.org/D136450 Added: clang/include/clang/ExtractAPI/APIIgnoresList.h clang/lib/ExtractAPI/APIIgnoresList.cpp clang/test/Driver/extract-api-unknown-ignore-diag.h clang/test/ExtractAPI/ignored-symbols.c Modified: clang/include/clang/Basic/DiagnosticFrontendKinds.td clang/include/clang/Driver/Options.td clang/include/clang/ExtractAPI/FrontendActions.h clang/include/clang/ExtractAPI/Serialization/SerializerBase.h clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h clang/include/clang/Frontend/FrontendOptions.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/ExtractAPI/CMakeLists.txt clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp Removed: diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 3e87f6256e0aa..07ecbe332f8b3 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -331,4 +331,7 @@ def warn_profile_data_misexpect : Warning< InGroup; } // end of instrumentation issue category +def err_extract_api_ignores_file_not_found : + Error<"file '%0' specified by '--extract-api-ignores=' not found">, DefaultFatal; + } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 2ab40ac6c9639..0f5b6d83330e1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1121,6 +1121,9 @@ def extract_api : Flag<["-"], "extract-api">, Flags<[CC1Option]>, Group; def product_name_EQ: Joined<["--"], "product-name=">, Flags<[CC1Option]>, MarshallingInfoString>; +def extract_api_ignores_EQ: Joined<["--"], "extract-api-ignores=">, Flags<[CC1Option]>, +HelpText<"File containing a new line separated list of API symbols to ignore when extracting API information.">, +MarshallingInfoString>; def e : JoinedOrSeparate<["-"], "e">, Flags<[LinkerInput]>, Group; def fmax_tokens_EQ : Joined<["-"], "fmax-tokens=">, Group, Flags<[CC1Option]>, HelpText<"Max total number of preprocessed tokens for -Wmax-tokens.">, diff --git a/clang/include/clang/ExtractAPI/APIIgnoresList.h b/clang/include/clang/ExtractAPI/APIIgnoresList.h new file mode 100644 index 0..43c546102a2d6 --- /dev/null +++ b/clang/include/clang/ExtractAPI/APIIgnoresList.h @@ -0,0 +1,74 @@ +//===- ExtractAPI/APIIgnoresList.h ---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +/// +/// \file This file defines APIIgnoresList which is a type that allows querying +/// a file containing symbols to ignore when extracting API information. +/// +//===--===// + +#ifndef LLVM_CLANG_API_IGNORES_LIST_H +#define LLVM_CLANG_API_IGNORES_LIST_H + +#include "clang/Basic/FileManager.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include + +namespace llvm { +class MemoryBuffer; +} // namespace llvm + +namespace clang { +namespace extractapi { + +struct IgnoresFileNotFound : public llvm::ErrorInfo { + std::string Path; + static char ID; + + explicit IgnoresFileNotFound(StringRef Path) : Path(Path) {} + + virtual void log(llvm::raw_ostream ) const override; + + virtual std::error_code convertToErrorCode() const override; +}; + +/// A type that provides access to a new line separated list of symbol names to +/// ignore when extracting API information. +struct APIIgnoresList { + /// The API to use for generating from the file at \p IgnoresFilePath. + /// + /// \returns an initialized APIIgnoresList or an Error. + static llvm::Expected create(llvm::StringRef IgnoresFilePath, + FileManager ); + + APIIgnoresList() = default; + + /// Check if \p SymbolName is specified in the APIIgnoresList and if it should +
[clang] b6da16f - [clang][ExtractAPI] Ignore fully anonymous RecordDecls
Author: Daniel Grumberg Date: 2022-10-13T11:53:53+01:00 New Revision: b6da16ffb9d5a47c16fa377097809c6592132d34 URL: https://github.com/llvm/llvm-project/commit/b6da16ffb9d5a47c16fa377097809c6592132d34 DIFF: https://github.com/llvm/llvm-project/commit/b6da16ffb9d5a47c16fa377097809c6592132d34.diff LOG: [clang][ExtractAPI] Ignore fully anonymous RecordDecls ExtractAPI was emitting a separate symbol for anonymous record declaration that define the type of a member of another record declaration. Now ExtractAPI ignores these declarations and just records the existence of the actual member. Differential Revision: https://reviews.llvm.org/D135804 Added: clang/test/ExtractAPI/anonymous_record_no_typedef.c Modified: clang/lib/ExtractAPI/ExtractAPIConsumer.cpp Removed: diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index 4a97ee9922ddd..2333f81fd3a36 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -401,6 +401,9 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { StringRef Name = Decl->getName(); if (Name.empty()) Name = getTypedefName(Decl); +if (Name.empty()) + return true; + StringRef USR = API.recordUSR(Decl); PresumedLoc Loc = Context.getSourceManager().getPresumedLoc(Decl->getLocation()); diff --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c b/clang/test/ExtractAPI/anonymous_record_no_typedef.c new file mode 100644 index 0..6f7156ff1decb --- /dev/null +++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c @@ -0,0 +1,396 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \ +// RUN: %t/reference.output.json.in >> %t/reference.output.json +// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \ +// RUN: -x c-header %t/input.h -o %t/output.json -verify + +// Generator version is not consistent across test runs, normalize it. +// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ +// RUN: %t/output.json >> %t/output-normalized.json +// RUN: diff %t/reference.output.json %t/output-normalized.json + +//--- input.h +/// A Vehicle +struct Vehicle { +/// The type of vehicle. +enum { +Bicycle, +Car +} type; + +/// The information about the vehicle. +struct { +int wheels; +char *name; +} information; +}; +// expected-no-diagnostics + +//--- reference.output.json.in +{ + "metadata": { +"formatVersion": { + "major": 0, + "minor": 5, + "patch": 3 +}, +"generator": "?" + }, + "module": { +"name": "", +"platform": { + "architecture": "arm64", + "operatingSystem": { +"minimumVersion": { + "major": 11, + "minor": 0, + "patch": 0 +}, +"name": "macosx" + }, + "vendor": "apple" +} + }, + "relationships": [ +{ + "kind": "memberOf", + "source": "c:@S@Vehicle@E@input.h@64@Bicycle", + "target": "c:@S@Vehicle@E@input.h@64" +}, +{ + "kind": "memberOf", + "source": "c:@S@Vehicle@E@input.h@64@Car", + "target": "c:@S@Vehicle@E@input.h@64" +}, +{ + "kind": "memberOf", + "source": "c:@S@Vehicle@FI@type", + "target": "c:@S@Vehicle" +}, +{ + "kind": "memberOf", + "source": "c:@S@Vehicle@FI@information", + "target": "c:@S@Vehicle" +} + ], + "symbols": [ +{ + "accessLevel": "public", + "declarationFragments": [ +{ + "kind": "keyword", + "spelling": "enum" +}, +{ + "kind": "text", + "spelling": ": " +}, +{ + "kind": "typeIdentifier", + "preciseIdentifier": "c:i", + "spelling": "unsigned int" +} + ], + "docComment": { +"lines": [ + { +"range": { + "end": { +"character": 29, +"line": 3 + }, + "start": { +"character": 9, +"line": 3 + } +}, +"text": "The type of vehicle." + } +] + }, + "identifier": { +"interfaceLanguage": "c", +"precise": "c:@S@Vehicle@E@input.h@64" + }, + "kind": { +"displayName": "Enumeration", +"identifier": "c.enum" + }, + "location": { +"position": { + "character": 5, + "line": 4 +}, +"uri": "file://INPUT_DIR/input.h" + }, + "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "Vehicle::(anonymous)" + } +], +"title": "Vehicle::(anonymous)" + }, + "pathComponents": [ +
[clang] 57c9780 - [clang][ExtractAPI] Record availability information on all platforms
Author: Daniel Grumberg Date: 2022-08-19T14:54:52-07:00 New Revision: 57c9780d60b15baf0eba4393857affce47f60aa7 URL: https://github.com/llvm/llvm-project/commit/57c9780d60b15baf0eba4393857affce47f60aa7 DIFF: https://github.com/llvm/llvm-project/commit/57c9780d60b15baf0eba4393857affce47f60aa7.diff LOG: [clang][ExtractAPI] Record availability information on all platforms Currently ExtractAPI only emits availability information for the current platform. This makes it easy for clients to get all availability information for a given symbol in one invocation as opposed to having to invoke clang once per-platform and then merge the symbol-graphs. Differential Revision: https://reviews.llvm.org/D130918 Added: clang/lib/ExtractAPI/AvailabilityInfo.cpp clang/test/ExtractAPI/availability.c Modified: clang/include/clang/ExtractAPI/API.h clang/include/clang/ExtractAPI/AvailabilityInfo.h clang/lib/ExtractAPI/API.cpp clang/lib/ExtractAPI/CMakeLists.txt clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp Removed: diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index 53db46ca44c13..b77d76d500df6 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -58,7 +58,7 @@ struct APIRecord { StringRef USR; StringRef Name; PresumedLoc Location; - AvailabilityInfo Availability; + AvailabilitySet Availabilities; LinkageInfo Linkage; /// Documentation comment lines attached to this symbol declaration. @@ -102,12 +102,13 @@ struct APIRecord { APIRecord() = delete; APIRecord(RecordKind Kind, StringRef USR, StringRef Name, -PresumedLoc Location, const AvailabilityInfo , +PresumedLoc Location, AvailabilitySet Availabilities, LinkageInfo Linkage, const DocComment , DeclarationFragments Declaration, DeclarationFragments SubHeading) - : USR(USR), Name(Name), Location(Location), Availability(Availability), -Linkage(Linkage), Comment(Comment), Declaration(Declaration), -SubHeading(SubHeading), Kind(Kind) {} + : USR(USR), Name(Name), Location(Location), +Availabilities(std::move(Availabilities)), Linkage(Linkage), +Comment(Comment), Declaration(Declaration), SubHeading(SubHeading), +Kind(Kind) {} // Pure virtual destructor to make APIRecord abstract virtual ~APIRecord() = 0; @@ -118,13 +119,13 @@ struct GlobalFunctionRecord : APIRecord { FunctionSignature Signature; GlobalFunctionRecord(StringRef USR, StringRef Name, PresumedLoc Loc, - const AvailabilityInfo , - LinkageInfo Linkage, const DocComment , + AvailabilitySet Availabilities, LinkageInfo Linkage, + const DocComment , DeclarationFragments Declaration, DeclarationFragments SubHeading, FunctionSignature Signature) - : APIRecord(RK_GlobalFunction, USR, Name, Loc, Availability, Linkage, - Comment, Declaration, SubHeading), + : APIRecord(RK_GlobalFunction, USR, Name, Loc, std::move(Availabilities), + Linkage, Comment, Declaration, SubHeading), Signature(Signature) {} static bool classof(const APIRecord *Record) { @@ -138,12 +139,12 @@ struct GlobalFunctionRecord : APIRecord { /// This holds information associated with global functions. struct GlobalVariableRecord : APIRecord { GlobalVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc, - const AvailabilityInfo , - LinkageInfo Linkage, const DocComment , + AvailabilitySet Availabilities, LinkageInfo Linkage, + const DocComment , DeclarationFragments Declaration, DeclarationFragments SubHeading) - : APIRecord(RK_GlobalVariable, USR, Name, Loc, Availability, Linkage, - Comment, Declaration, SubHeading) {} + : APIRecord(RK_GlobalVariable, USR, Name, Loc, std::move(Availabilities), + Linkage, Comment, Declaration, SubHeading) {} static bool classof(const APIRecord *Record) { return Record->getKind() == RK_GlobalVariable; @@ -156,11 +157,10 @@ struct GlobalVariableRecord : APIRecord { /// This holds information associated with enum constants. struct EnumConstantRecord : APIRecord { EnumConstantRecord(StringRef USR, StringRef Name, PresumedLoc Loc, - const AvailabilityInfo , - const DocComment , + AvailabilitySet Availabilities, const DocComment , DeclarationFragments Declaration, DeclarationFragments SubHeading) - :
[clang] cef232f - [clang][ExtractAPI] Fix objc_property.m reference output
Author: Daniel Grumberg Date: 2022-07-27T11:34:17+01:00 New Revision: cef232ff3320ad1c85d403837d0b8c8b5ae7153f URL: https://github.com/llvm/llvm-project/commit/cef232ff3320ad1c85d403837d0b8c8b5ae7153f DIFF: https://github.com/llvm/llvm-project/commit/cef232ff3320ad1c85d403837d0b8c8b5ae7153f.diff LOG: [clang][ExtractAPI] Fix objc_property.m reference output After landing 7f0387de4c600af185b2db8d748f530444fe03cd I forgot to update this new test. Added: Modified: clang/test/ExtractAPI/objc_property.m Removed: diff --git a/clang/test/ExtractAPI/objc_property.m b/clang/test/ExtractAPI/objc_property.m index 7cc17291ac76..1b50950d4424 100644 --- a/clang/test/ExtractAPI/objc_property.m +++ b/clang/test/ExtractAPI/objc_property.m @@ -195,6 +195,10 @@ @interface Interface (Category) "preciseIdentifier": "c:I", "spelling": "int" }, +{ + "kind": "text", + "spelling": " " +}, { "kind": "identifier", "spelling": "myInterfaceTypeProp" @@ -283,6 +287,10 @@ @interface Interface (Category) "preciseIdentifier": "c:I", "spelling": "int" }, +{ + "kind": "text", + "spelling": " " +}, { "kind": "identifier", "spelling": "myInterfaceInstanceProp" @@ -379,6 +387,10 @@ @interface Interface (Category) "preciseIdentifier": "c:I", "spelling": "int" }, +{ + "kind": "text", + "spelling": " " +}, { "kind": "identifier", "spelling": "myCategoryTypeProp" @@ -467,6 +479,10 @@ @interface Interface (Category) "preciseIdentifier": "c:I", "spelling": "int" }, +{ + "kind": "text", + "spelling": " " +}, { "kind": "identifier", "spelling": "myCategoryInstanceProp" @@ -613,6 +629,10 @@ @interface Interface (Category) "preciseIdentifier": "c:I", "spelling": "int" }, +{ + "kind": "text", + "spelling": " " +}, { "kind": "identifier", "spelling": "myProtocolTypeProp" @@ -701,6 +721,10 @@ @interface Interface (Category) "preciseIdentifier": "c:I", "spelling": "int" }, +{ + "kind": "text", + "spelling": " " +}, { "kind": "identifier", "spelling": "myProtocolInstanceProp" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d3fc779 - [clang][ExtractAPI] Ensure that class properties have a kind of "Type Property"
Author: Daniel Grumberg Date: 2022-07-27T11:03:34+01:00 New Revision: d3fc779e4295b0bf726008580ddd99c8e86c2c0c URL: https://github.com/llvm/llvm-project/commit/d3fc779e4295b0bf726008580ddd99c8e86c2c0c DIFF: https://github.com/llvm/llvm-project/commit/d3fc779e4295b0bf726008580ddd99c8e86c2c0c.diff LOG: [clang][ExtractAPI] Ensure that class properties have a kind of "Type Property" Generated symbol graphs should distinguish between type properties and instance properties. Differential Revision: https://reviews.llvm.org/D130581 Added: clang/test/ExtractAPI/objc_property.m Modified: clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp Removed: diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 709b781968bf7..6ef7badfa66f4 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -351,7 +351,7 @@ Object serializeSymbolKind(const APIRecord , Language Lang) { Kind["displayName"] = "Instance Variable"; break; case APIRecord::RK_ObjCMethod: -if (dyn_cast()->IsInstanceMethod) { +if (cast()->IsInstanceMethod) { Kind["identifier"] = AddLangPrefix("method"); Kind["displayName"] = "Instance Method"; } else { @@ -360,8 +360,13 @@ Object serializeSymbolKind(const APIRecord , Language Lang) { } break; case APIRecord::RK_ObjCProperty: -Kind["identifier"] = AddLangPrefix("property"); -Kind["displayName"] = "Instance Property"; +if (cast()->isClassProperty()) { + Kind["identifier"] = AddLangPrefix("type.property"); + Kind["displayName"] = "Type Property"; +} else { + Kind["identifier"] = AddLangPrefix("property"); + Kind["displayName"] = "Instance Property"; +} break; case APIRecord::RK_ObjCInterface: Kind["identifier"] = AddLangPrefix("class"); diff --git a/clang/test/ExtractAPI/objc_property.m b/clang/test/ExtractAPI/objc_property.m new file mode 100644 index 0..7cc17291ac76c --- /dev/null +++ b/clang/test/ExtractAPI/objc_property.m @@ -0,0 +1,745 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \ +// RUN: %t/reference.output.json.in >> %t/reference.output.json +// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx -x objective-c-header %t/input.h -o %t/output.json -verify + +// Generator version is not consistent across test runs, normalize it. +// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ +// RUN: %t/output.json >> %t/output-normalized.json +// RUN: diff %t/reference.output.json %t/output-normalized.json + +//--- input.h +@protocol Protocol +@property(class) int myProtocolTypeProp; +@property int myProtocolInstanceProp; +@end + +@interface Interface +@property(class) int myInterfaceTypeProp; +@property int myInterfaceInstanceProp; +@end + +@interface Interface (Category) +@property(class) int myCategoryTypeProp; +@property int myCategoryInstanceProp; +@end +// expected-no-diagnostics + +//--- reference.output.json.in +{ + "metadata": { +"formatVersion": { + "major": 0, + "minor": 5, + "patch": 3 +}, +"generator": "?" + }, + "module": { +"name": "", +"platform": { + "architecture": "arm64", + "operatingSystem": { +"minimumVersion": { + "major": 11, + "minor": 0, + "patch": 0 +}, +"name": "macosx" + }, + "vendor": "apple" +} + }, + "relationships": [ +{ + "kind": "memberOf", + "source": "c:objc(cs)Interface(cpy)myInterfaceTypeProp", + "target": "c:objc(cs)Interface" +}, +{ + "kind": "memberOf", + "source": "c:objc(cs)Interface(py)myInterfaceInstanceProp", + "target": "c:objc(cs)Interface" +}, +{ + "kind": "memberOf", + "source": "c:objc(cs)Interface(cpy)myCategoryTypeProp", + "target": "c:objc(cs)Interface" +}, +{ + "kind": "memberOf", + "source": "c:objc(cs)Interface(py)myCategoryInstanceProp", + "target": "c:objc(cs)Interface" +}, +{ + "kind": "conformsTo", + "source": "c:objc(cs)Interface", + "target": "c:objc(pl)Protocol" +}, +{ + "kind": "memberOf", + "source": "c:objc(pl)Protocol(cpy)myProtocolTypeProp", + "target": "c:objc(pl)Protocol" +}, +{ + "kind": "memberOf", + "source": "c:objc(pl)Protocol(py)myProtocolInstanceProp", + "target": "c:objc(pl)Protocol" +} + ], + "symbols": [ +{ + "accessLevel": "public", + "declarationFragments": [ +{ + "kind": "keyword", + "spelling": "@interface" +}, +{ + "kind": "text", + "spelling": " " +}, +{ + "kind":
[clang] 7f0387d - [clang][ExtractAPI] Add a space between type and name in property declaration fragments
Author: Daniel Grumberg Date: 2022-07-27T11:02:21+01:00 New Revision: 7f0387de4c600af185b2db8d748f530444fe03cd URL: https://github.com/llvm/llvm-project/commit/7f0387de4c600af185b2db8d748f530444fe03cd DIFF: https://github.com/llvm/llvm-project/commit/7f0387de4c600af185b2db8d748f530444fe03cd.diff LOG: [clang][ExtractAPI] Add a space between type and name in property declaration fragments Differential Revision: https://reviews.llvm.org/D130583 Added: Modified: clang/lib/ExtractAPI/DeclarationFragments.cpp clang/test/ExtractAPI/objc_category.m clang/test/ExtractAPI/objc_interface.m Removed: diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 75d360a3ba167..40ba124bc4d81 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -692,6 +692,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty( return Fragments.appendSpace() .append(getFragmentsForType(Property->getType(), Property->getASTContext(), After)) + .appendSpace() .append(Property->getName(), DeclarationFragments::FragmentKind::Identifier) .append(std::move(After)); diff --git a/clang/test/ExtractAPI/objc_category.m b/clang/test/ExtractAPI/objc_category.m index 946f01eaeb334..56bac43a11cdc 100644 --- a/clang/test/ExtractAPI/objc_category.m +++ b/clang/test/ExtractAPI/objc_category.m @@ -317,6 +317,10 @@ + (void)ClassMethod; "preciseIdentifier": "c:I", "spelling": "int" }, +{ + "kind": "text", + "spelling": " " +}, { "kind": "identifier", "spelling": "Property" diff --git a/clang/test/ExtractAPI/objc_interface.m b/clang/test/ExtractAPI/objc_interface.m index bd1f23ed1f095..740a215400d9c 100644 --- a/clang/test/ExtractAPI/objc_interface.m +++ b/clang/test/ExtractAPI/objc_interface.m @@ -462,6 +462,10 @@ - (char)getIvar; "preciseIdentifier": "c:i", "spelling": "unsigned int" }, +{ + "kind": "text", + "spelling": " " +}, { "kind": "identifier", "spelling": "Property" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits