[clang] e87e55e - Make ASTFileSignature an array of 20 uint8_t instead of 5 uint32_t
Author: Daniel Grumberg Date: 2020-06-11T09:12:29+01:00 New Revision: e87e55edbc798c1c73963151f114df775b1ec460 URL: https://github.com/llvm/llvm-project/commit/e87e55edbc798c1c73963151f114df775b1ec460 DIFF: https://github.com/llvm/llvm-project/commit/e87e55edbc798c1c73963151f114df775b1ec460.diff LOG: Make ASTFileSignature an array of 20 uint8_t instead of 5 uint32_t Reviewers: aprantl, dexonsmith, Bigcheese Subscribers: arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D81347 Added: Modified: clang/include/clang/Basic/Module.h clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/GlobalModuleIndex.cpp Removed: diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index b14f6b59dd8c..6b932a9a84d0 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -20,9 +20,9 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -52,12 +53,33 @@ class TargetInfo; using ModuleId = SmallVector, 2>; /// The signature of a module, which is a hash of the AST content. -struct ASTFileSignature : std::array { - ASTFileSignature(std::array S = {{0}}) - : std::array(std::move(S)) {} +struct ASTFileSignature : std::array { + using BaseT = std::array; + + static constexpr size_t size = std::tuple_size::value; + + ASTFileSignature(BaseT S = {{0}}) : BaseT(std::move(S)) {} + + explicit operator bool() const { return *this != BaseT({{0}}); } + + static ASTFileSignature create(StringRef Bytes) { +return create(Bytes.bytes_begin(), Bytes.bytes_end()); + } + + static ASTFileSignature createDISentinel() { +ASTFileSignature Sentinel; +Sentinel.fill(0xFF); +return Sentinel; + } + + template + static ASTFileSignature create(InputIt First, InputIt Last) { +assert(std::distance(First, Last) == size && + "Wrong amount of bytes to create an ASTFileSignature"); - explicit operator bool() const { -return *this != std::array({{0}}); +ASTFileSignature Signature; +std::copy(First, Last, Signature.begin()); +return Signature; } }; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 65d513c8cf05..6965c4a1209c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2535,10 +2535,14 @@ llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod, // PCH files don't have a signature field in the control block, // but LLVM detects skeleton CUs by looking for a non-zero DWO id. // We use the lower 64 bits for debug info. -uint64_t Signature = -Mod.getSignature() -? (uint64_t)Mod.getSignature()[1] << 32 | Mod.getSignature()[0] -: ~1ULL; + +uint64_t Signature = 0; +if (const auto &ModSig = Mod.getSignature()) { + for (unsigned I = 0; I != sizeof(Signature); ++I) +Signature |= (uint64_t)ModSig[I] << (I * 8); +} else { + Signature = ~1ULL; +} llvm::DIBuilder DIB(CGM.getModule()); SmallString<0> PCM; if (!llvm::sys::path::is_absolute(Mod.getASTFile())) diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp index 284e8022a3c4..0c7e5f4598f8 100644 --- a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp +++ b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp @@ -173,8 +173,8 @@ class PCHContainerGenerator : public ASTConsumer { // Prepare CGDebugInfo to emit debug info for a clang module. auto *DI = Builder->getModuleDebugInfo(); StringRef ModuleName = llvm::sys::path::filename(MainFileName); -DI->setPCHDescriptor({ModuleName, "", OutputFileName, - ASTFileSignature{{{~0U, ~0U, ~0U, ~0U, ~1U); +DI->setPCHDescriptor( +{ModuleName, "", OutputFileName, ASTFileSignature::createDISentinel()}); DI->setModuleMap(MMap); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 87987064b747..673b65d543fc 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -2791,10 +2791,10 @@ ASTReader::ReadControlBlock(ModuleFile &F, ReadUntranslatedSourceLocation(Record[Idx++]); off_t StoredSize = (off_t)Record[Idx++];
[clang] afa42e4 - [NFC] Make formatting changes to ASTBitCodes.h ahead of a functional change
Author: Daniel Grumberg Date: 2020-06-11T10:25:04+01:00 New Revision: afa42e4c9253ca111fdcb6238a0da34129475911 URL: https://github.com/llvm/llvm-project/commit/afa42e4c9253ca111fdcb6238a0da34129475911 DIFF: https://github.com/llvm/llvm-project/commit/afa42e4c9253ca111fdcb6238a0da34129475911.diff LOG: [NFC] Make formatting changes to ASTBitCodes.h ahead of a functional change Added: Modified: clang/include/clang/Serialization/ASTBitCodes.h Removed: diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index a98d12645985..54d3e6ab8917 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -30,84 +30,84 @@ namespace clang { namespace serialization { -/// AST file major version number supported by this version of -/// Clang. -/// -/// Whenever the AST file format changes in a way that makes it -/// incompatible with previous versions (such that a reader -/// designed for the previous version could not support reading -/// the new version), this number should be increased. -/// -/// Version 4 of AST files also requires that the version control branch and -/// revision match exactly, since there is no backward compatibility of -/// AST files at this time. -const unsigned VERSION_MAJOR = 10; - -/// AST file minor version number supported by this version of -/// Clang. -/// -/// Whenever the AST format changes in a way that is still -/// compatible with previous versions (such that a reader designed -/// for the previous version could still support reading the new -/// version by ignoring new kinds of subblocks), this number -/// should be increased. -const unsigned VERSION_MINOR = 0; - -/// An ID number that refers to an identifier in an AST file. -/// -/// The ID numbers of identifiers are consecutive (in order of discovery) -/// and start at 1. 0 is reserved for NULL. -using IdentifierID = uint32_t; - -/// An ID number that refers to a declaration in an AST file. -/// -/// The ID numbers of declarations are consecutive (in order of -/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. -/// At the start of a chain of precompiled headers, declaration ID 1 is -/// used for the translation unit declaration. -using DeclID = uint32_t; - -// FIXME: Turn these into classes so we can have some type safety when -// we go from local ID to global and vice-versa. -using LocalDeclID = DeclID; -using GlobalDeclID = DeclID; - -/// An ID number that refers to a type in an AST file. -/// -/// The ID of a type is partitioned into two parts: the lower -/// three bits are used to store the const/volatile/restrict -/// qualifiers (as with QualType) and the upper bits provide a -/// type index. The type index values are partitioned into two -/// sets. The values below NUM_PREDEF_TYPE_IDs are predefined type -/// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a -/// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are -/// other types that have serialized representations. -using TypeID = uint32_t; - -/// A type index; the type ID with the qualifier bits removed. -class TypeIdx { - uint32_t Idx = 0; - -public: - TypeIdx() = default; - explicit TypeIdx(uint32_t index) : Idx(index) {} - - uint32_t getIndex() const { return Idx; } - - TypeID asTypeID(unsigned FastQuals) const { -if (Idx == uint32_t(-1)) - return TypeID(-1); - -return (Idx << Qualifiers::FastWidth) | FastQuals; - } - - static TypeIdx fromTypeID(TypeID ID) { -if (ID == TypeID(-1)) - return TypeIdx(-1); - -return TypeIdx(ID >> Qualifiers::FastWidth); - } -}; +/// AST file major version number supported by this version of +/// Clang. +/// +/// Whenever the AST file format changes in a way that makes it +/// incompatible with previous versions (such that a reader +/// designed for the previous version could not support reading +/// the new version), this number should be increased. +/// +/// Version 4 of AST files also requires that the version control branch and +/// revision match exactly, since there is no backward compatibility of +/// AST files at this time. +const unsigned VERSION_MAJOR = 10; + +/// AST file minor version number supported by this version of +/// Clang. +/// +/// Whenever the AST format changes in a way that is still +/// compatible with previous versions (such that a reader designed +/// for the previous version could still support reading the new +/// version by ignoring new kinds of subblocks), this number +/// should be increased. +const unsigned VERSION_MINOR = 0; + +/// An ID number that re
[clang] bb8c7e7 - Add AST_SIGNATURE record to unhashed control block of PCM files
Author: Daniel Grumberg Date: 2020-06-11T14:09:07+01:00 New Revision: bb8c7e756c51bb3dc05b30671fa4c64f48e41c39 URL: https://github.com/llvm/llvm-project/commit/bb8c7e756c51bb3dc05b30671fa4c64f48e41c39 DIFF: https://github.com/llvm/llvm-project/commit/bb8c7e756c51bb3dc05b30671fa4c64f48e41c39.diff LOG: Add AST_SIGNATURE record to unhashed control block of PCM files Summary: This record is constructed by hashing the bytes of the AST block in a similiar fashion to the SIGNATURE record. This new signature only means anything if the AST block is fully relocatable, i.e. it does not embed absolute offsets within the PCM file. This change ensure this does not happen by replacing these offsets with offsets relative to the nearest relevant subblock of the AST block. Reviewers: Bigcheese, dexonsmith Subscribers: dexonsmith, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D80383 Added: clang/test/Modules/ASTSignature.c clang/test/Modules/Inputs/ASTHash/module.modulemap clang/test/Modules/Inputs/ASTHash/my_header_1.h clang/test/Modules/Inputs/ASTHash/my_header_2.h Modified: clang/include/clang/Serialization/ASTBitCodes.h clang/include/clang/Serialization/ASTReader.h clang/include/clang/Serialization/ASTWriter.h clang/include/clang/Serialization/ModuleFile.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/ASTWriterDecl.cpp Removed: diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 54d3e6ab8917..4008f11daa15 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -41,7 +41,7 @@ namespace serialization { /// Version 4 of AST files also requires that the version control branch and /// revision match exactly, since there is no backward compatibility of /// AST files at this time. -const unsigned VERSION_MAJOR = 10; +const unsigned VERSION_MAJOR = 11; /// AST file minor version number supported by this version of /// Clang. @@ -242,14 +242,16 @@ class TypeIdx { /// Raw source location. unsigned Loc = 0; - /// Offset in the AST file. Keep structure alignment 32-bit and avoid - /// padding gap because undefined value in the padding affects AST hash. + /// Offset relative to the start of the DECLTYPES_BLOCK block. Keep + /// structure alignment 32-bit and avoid padding gap because undefined + /// value in the padding affects AST hash. UnderalignedInt64 BitOffset; DeclOffset() = default; - DeclOffset(SourceLocation Loc, uint64_t BitOffset) { + DeclOffset(SourceLocation Loc, uint64_t BitOffset, + uint64_t DeclTypesBlockStartOffset) { setLocation(Loc); -setBitOffset(BitOffset); +setBitOffset(BitOffset, DeclTypesBlockStartOffset); } void setLocation(SourceLocation L) { @@ -260,12 +262,13 @@ class TypeIdx { return SourceLocation::getFromRawEncoding(Loc); } - void setBitOffset(uint64_t Offset) { -BitOffset.setBitOffset(Offset); + void setBitOffset(uint64_t Offset, +const uint64_t DeclTypesBlockStartOffset) { +BitOffset.setBitOffset(Offset - DeclTypesBlockStartOffset); } - uint64_t getBitOffset() const { -return BitOffset.getBitOffset(); + uint64_t getBitOffset(const uint64_t DeclTypesBlockStartOffset) const { +return BitOffset.getBitOffset() + DeclTypesBlockStartOffset; } }; @@ -394,6 +397,9 @@ class TypeIdx { /// Record code for the signature that identifiers this AST file. SIGNATURE = 1, + /// Record code for the content hash of the AST block. + AST_BLOCK_HASH, + /// Record code for the diagnostic options table. DIAGNOSTIC_OPTIONS, diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index aa93c702bed1..a80366f0ee04 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1890,7 +1890,8 @@ class ASTReader /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the /// specified cursor. Read the abbreviations that are at the top of the block /// and then leave the cursor pointing into the block. - static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID); + static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID, + uint64_t *StartOfBlockOffset = nullptr); /// Finds all the visible declarations with a given name. /// The current implementation of this method just loads the entire diff --git a/clang/include/clang/Serialization/ASTWriter.
[clang] fccd29d - Merge TableGen files used for clang options
Author: Daniel Grumberg Date: 2020-07-09T18:28:51+01:00 New Revision: fccd29dddee92ffa7cd8a9adec6e626760538dae URL: https://github.com/llvm/llvm-project/commit/fccd29dddee92ffa7cd8a9adec6e626760538dae DIFF: https://github.com/llvm/llvm-project/commit/fccd29dddee92ffa7cd8a9adec6e626760538dae.diff LOG: Merge TableGen files used for clang options Summary: Putting all the options in the same file is needed so they can be ordered based on the dependencies between them. Reviewers: Bigcheese, jdoerfert Subscribers: dexonsmith, sstefan1, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D82574 Added: Modified: clang/include/clang/Driver/Options.td Removed: clang/include/clang/Driver/CLCompatOptions.td diff --git a/clang/include/clang/Driver/CLCompatOptions.td b/clang/include/clang/Driver/CLCompatOptions.td deleted file mode 100644 index 17d248a3c5ad.. --- a/clang/include/clang/Driver/CLCompatOptions.td +++ /dev/null @@ -1,470 +0,0 @@ -//===--- CLCompatOptions.td - Options for clang-cl ===// -// -// 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 -// -//===--===// -// -// This file defines the options accepted by clang-cl. -// -//===--===// - -def cl_Group : OptionGroup<"">, Flags<[CLOption]>, - HelpText<"CL.EXE COMPATIBILITY OPTIONS">; - -def cl_compile_Group : OptionGroup<"">, - Group; - -def cl_ignored_Group : OptionGroup<"">, - Group; - -class CLFlag : Option<["/", "-"], name, KIND_FLAG>, - Group, Flags<[CLOption, DriverOption]>; - -class CLCompileFlag : Option<["/", "-"], name, KIND_FLAG>, - Group, Flags<[CLOption, DriverOption]>; - -class CLIgnoredFlag : Option<["/", "-"], name, KIND_FLAG>, - Group, Flags<[CLOption, DriverOption]>; - -class CLJoined : Option<["/", "-"], name, KIND_JOINED>, - Group, Flags<[CLOption, DriverOption]>; - -class CLCompileJoined : Option<["/", "-"], name, KIND_JOINED>, - Group, Flags<[CLOption, DriverOption]>; - -class CLIgnoredJoined : Option<["/", "-"], name, KIND_JOINED>, - Group, Flags<[CLOption, DriverOption, HelpHidden]>; - -class CLJoinedOrSeparate : Option<["/", "-"], name, - KIND_JOINED_OR_SEPARATE>, Group, Flags<[CLOption, DriverOption]>; - -class CLCompileJoinedOrSeparate : Option<["/", "-"], name, - KIND_JOINED_OR_SEPARATE>, Group, - Flags<[CLOption, DriverOption]>; - -class CLRemainingArgsJoined : Option<["/", "-"], name, - KIND_REMAINING_ARGS_JOINED>, Group, Flags<[CLOption, DriverOption]>; - -// Aliases: -// (We don't put any of these in cl_compile_Group as the options they alias are -// already in the right group.) - -def _SLASH_Brepro : CLFlag<"Brepro">, - HelpText<"Do not write current time into COFF output (breaks link.exe /incremental)">, - Alias; -def _SLASH_Brepro_ : CLFlag<"Brepro-">, - HelpText<"Write current time into COFF output (default)">, - Alias; -def _SLASH_C : CLFlag<"C">, - HelpText<"Do not discard comments when preprocessing">, Alias; -def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias; -def _SLASH_d1PP : CLFlag<"d1PP">, - HelpText<"Retain macro definitions in /E mode">, Alias; -def _SLASH_d1reportAllClassLayout : CLFlag<"d1reportAllClassLayout">, - HelpText<"Dump record layout information">, - Alias, AliasArgs<["-fdump-record-layouts"]>; -def _SLASH_diagnostics_caret : CLFlag<"diagnostics:caret">, - HelpText<"Enable caret and column diagnostics (default)">; -def _SLASH_diagnostics_column : CLFlag<"diagnostics:column">, - HelpText<"Disable caret diagnostics but keep column info">; -def _SLASH_diagnostics_classic : CLFlag<"diagnostics:classic">, - HelpText<"Disable column and caret diagnostics">; -def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">, - MetaVarName<"">, Alias; -def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias; -def _SLASH_fp_except : CLFlag<"fp:except">, HelpText<"">, Alias; -def _SLASH_fp_except_ : CLFlag<"fp:except-">, - HelpText<"">, Alias; -def _SLASH_fp_fast : CLFlag<"fp:fast">, HelpText<"">, Alias; -def _SLASH_fp_precise : CLFlag<"fp:precise">, - HelpText<"">, Alias; -def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias; -def _SLASH_GA : CLFlag<"GA">, Alias, AliasArgs<["local-exec"]>, - HelpText<"Assume thread-local variables are defined in the executable">; -def _SLASH_GR : CLFlag<"GR">, HelpText<"Emit RTTI data (default)">; -def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Do not emit RTTI data">; -def _SLASH_GF : CLIgnoredFlag<"GF">, - HelpText<"Enable string pooling (default)">; -def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, - Alias; -def _SLASH_GS : CLFlag<"GS">, - HelpT
[clang] 50f2433 - Add diagnostic option backing field for -fansi-escape-codes
Author: Daniel Grumberg Date: 2020-07-10T07:26:56+01:00 New Revision: 50f24331fd91e70de6bf6c3efe45272ddfc711fd URL: https://github.com/llvm/llvm-project/commit/50f24331fd91e70de6bf6c3efe45272ddfc711fd DIFF: https://github.com/llvm/llvm-project/commit/50f24331fd91e70de6bf6c3efe45272ddfc711fd.diff LOG: Add diagnostic option backing field for -fansi-escape-codes Summary: Keep track of -fansi-escape-codes in DiagnosticOptions and move the option to the new option parsing system. Depends on D82860 Reviewers: Bigcheese Subscribers: dexonsmith, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D82874 Added: Modified: clang/include/clang/Basic/DiagnosticOptions.def clang/include/clang/Driver/Options.td clang/lib/Frontend/CompilerInvocation.cpp Removed: diff --git a/clang/include/clang/Basic/DiagnosticOptions.def b/clang/include/clang/Basic/DiagnosticOptions.def index 6d1a1af92821..a946b5c6be8e 100644 --- a/clang/include/clang/Basic/DiagnosticOptions.def +++ b/clang/include/clang/Basic/DiagnosticOptions.def @@ -65,6 +65,7 @@ VALUE_DIAGOPT(ShowCategories, 2, 0) /// Show categories: 0 -> none, 1 -> Number, ENUM_DIAGOPT(Format, TextDiagnosticFormat, 2, Clang) /// Format for diagnostics: DIAGOPT(ShowColors, 1, 0) /// Show diagnostics with ANSI color sequences. +DIAGOPT(UseANSIEscapeCodes, 1, 0) ENUM_DIAGOPT(ShowOverloads, OverloadsShown, 1, Ovl_All)/// Overload candidates to show. DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 113696aeec7f..c6acd745bfd0 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -849,7 +849,8 @@ def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group, Flags<[CoreOption, DriverOption]>; def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group; def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group, - Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">; + Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">, + MarshallingInfoFlag<"DiagnosticOpts->UseANSIEscapeCodes", "false">; def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group, Flags<[CC1Option]>, HelpText<"Treat each comma separated argument in as a documentation comment block command">, MetaVarName<"">; diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 6f6af917e3a3..64dcfa831824 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1580,8 +1580,6 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.AbsolutePath = Args.hasArg(OPT_fdiagnostics_absolute_paths); Opts.ShowOptionNames = !Args.hasArg(OPT_fno_diagnostics_show_option); - llvm::sys::Process::UseANSIEscapeCodes(Args.hasArg(OPT_fansi_escape_codes)); - // Default behavior is to not to show note include stacks. Opts.ShowNoteIncludeStack = false; if (Arg *A = Args.getLastArg(OPT_fdiagnostics_show_note_include_stack, @@ -3724,6 +3722,10 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, } Success &= Res.parseSimpleArgs(Args, Diags); + + llvm::sys::Process::UseANSIEscapeCodes( + Res.DiagnosticOpts->UseANSIEscapeCodes); + Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags); Success &= ParseMigratorArgs(Res.getMigratorOpts(), Args); ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0555db0 - Normalize default value for -triple correctly
Author: Daniel Grumberg Date: 2020-07-10T13:58:48+01:00 New Revision: 0555db0a5df4d669ce4c2125668ec7a8a42fcd9d URL: https://github.com/llvm/llvm-project/commit/0555db0a5df4d669ce4c2125668ec7a8a42fcd9d DIFF: https://github.com/llvm/llvm-project/commit/0555db0a5df4d669ce4c2125668ec7a8a42fcd9d.diff LOG: Normalize default value for -triple correctly Added: Modified: clang/include/clang/Driver/Options.td Removed: diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index e24914e9e4b6..042d66a1b61a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3456,7 +3456,7 @@ def target_feature : Separate<["-"], "target-feature">, HelpText<"Target specific attributes">; def triple : Separate<["-"], "triple">, HelpText<"Specify target triple (e.g. i686-apple-darwin9)">, - MarshallingInfoString<"TargetOpts->Triple", "llvm::sys::getDefaultTargetTriple()", "std::string">, + MarshallingInfoString<"TargetOpts->Triple", "llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple())", "std::string">, AlwaysEmit, Normalizer<"normalizeTriple">, DenormalizeString; def target_abi : Separate<["-"], "target-abi">, HelpText<"Target a particular ABI type">; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3607aac - Delete CC1Options.td, since it should have happened in D82574
Author: Daniel Grumberg Date: 2020-07-10T16:55:05+01:00 New Revision: 3607aacc59817f76bffb9b567f128871340d54d2 URL: https://github.com/llvm/llvm-project/commit/3607aacc59817f76bffb9b567f128871340d54d2 DIFF: https://github.com/llvm/llvm-project/commit/3607aacc59817f76bffb9b567f128871340d54d2.diff LOG: Delete CC1Options.td, since it should have happened in D82574 Added: Modified: Removed: clang/include/clang/Driver/CC1Options.td diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td deleted file mode 100644 index 5a7077ce9e46.. --- a/clang/include/clang/Driver/CC1Options.td +++ /dev/null @@ -1,946 +0,0 @@ -//===--- CC1Options.td - Options for clang -cc1 ---===// -// -// 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 -// -//===--===// -// -// This file defines the options accepted by clang -cc1 and clang -cc1as. -// -//===--===// - -let Flags = [CC1Option, NoDriverOption] in { - -//===--===// -// Target Options -//===--===// - -let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { - -def target_cpu : Separate<["-"], "target-cpu">, - HelpText<"Target a specific cpu type">; -def target_feature : Separate<["-"], "target-feature">, - HelpText<"Target specific attributes">; -def triple : Separate<["-"], "triple">, - HelpText<"Specify target triple (e.g. i686-apple-darwin9)">, - MarshallingInfoString<"TargetOpts->Triple", "llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple())", "std::string">, - AlwaysEmit, Normalizer<"normalizeTriple">, DenormalizeString; -def target_abi : Separate<["-"], "target-abi">, - HelpText<"Target a particular ABI type">; -def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">, - HelpText<"The version of target SDK used for compilation">; - -} - -def target_linker_version : Separate<["-"], "target-linker-version">, - HelpText<"Target linker version">; -def triple_EQ : Joined<["-"], "triple=">, Alias; -def mfpmath : Separate<["-"], "mfpmath">, - HelpText<"Which unit to use for fp math">; - -def fpadding_on_unsigned_fixed_point : Flag<["-"], "fpadding-on-unsigned-fixed-point">, - HelpText<"Force each unsigned fixed point type to have an extra bit of padding to align their scales with those of signed fixed point types">; -def fno_padding_on_unsigned_fixed_point : Flag<["-"], "fno-padding-on-unsigned-fixed-point">; - -//===--===// -// Analyzer Options -//===--===// - -def analysis_UnoptimizedCFG : Flag<["-"], "unoptimized-cfg">, - HelpText<"Generate unoptimized CFGs for all analyses">; -def analysis_CFGAddImplicitDtors : Flag<["-"], "cfg-add-implicit-dtors">, - HelpText<"Add C++ implicit destructors to CFGs for all analyses">; - -def analyzer_store : Separate<["-"], "analyzer-store">, - HelpText<"Source Code Analysis - Abstract Memory Store Models">; -def analyzer_store_EQ : Joined<["-"], "analyzer-store=">, Alias; - -def analyzer_constraints : Separate<["-"], "analyzer-constraints">, - HelpText<"Source Code Analysis - Symbolic Constraint Engines">; -def analyzer_constraints_EQ : Joined<["-"], "analyzer-constraints=">, - Alias; - -def analyzer_output : Separate<["-"], "analyzer-output">, - HelpText<"Source Code Analysis - Output Options">; -def analyzer_output_EQ : Joined<["-"], "analyzer-output=">, - Alias; - -def analyzer_purge : Separate<["-"], "analyzer-purge">, - HelpText<"Source Code Analysis - Dead Symbol Removal Frequency">; -def analyzer_purge_EQ : Joined<["-"], "analyzer-purge=">, Alias; - -def analyzer_opt_analyze_headers : Flag<["-"], "analyzer-opt-analyze-headers">, - HelpText<"Force the static analyzer to analyze functions defined in header files">; -def analyzer_opt_analyze_nested_blocks : Flag<["-"], "analyzer-opt-analyze-nested-blocks">, - HelpText<"Analyze the definitions of blocks in addition to functions">; -def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">, - HelpText<"Emit verbose output about the analyzer's progress">; -def analyze_function : Separate<["-"], "analyze-function">, - HelpText<"Run analysis on specific function (for C++ include parameters in name)">; -def analyze_function_EQ : Joined<["-"], "analyze-function=">, Alias; -def trim_egraph : Flag<["-"], "trim-egraph">, - HelpText<"Only show error-related paths in the analysis graph">; -def analyzer_
[clang] a2cffb1 - Remove clang options that were added back when merging the TableGen files
Author: Daniel Grumberg Date: 2020-07-10T17:54:44+01:00 New Revision: a2cffb11e287f0e35685ac404400edab12cae51e URL: https://github.com/llvm/llvm-project/commit/a2cffb11e287f0e35685ac404400edab12cae51e DIFF: https://github.com/llvm/llvm-project/commit/a2cffb11e287f0e35685ac404400edab12cae51e.diff LOG: Remove clang options that were added back when merging the TableGen files Added: Modified: clang/include/clang/Driver/Options.td Removed: diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 042d66a1b61a..e09b1b0b306f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3669,8 +3669,6 @@ def disable_O0_optnone : Flag<["-"], "disable-O0-optnone">, HelpText<"Disable adding the optnone attribute to functions at O0">; def disable_red_zone : Flag<["-"], "disable-red-zone">, HelpText<"Do not emit code that uses the red zone.">; -def dwarf_column_info : Flag<["-"], "dwarf-column-info">, - HelpText<"Turn on column location information.">; def dwarf_ext_refs : Flag<["-"], "dwarf-ext-refs">, HelpText<"Generate debug info with external references to clang modules" " or precompiled headers">; @@ -3739,8 +3737,6 @@ def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">, HelpText<"Limit float precision to the given value">; def split_stacks : Flag<["-"], "split-stacks">, HelpText<"Try to use a split stack if possible.">; -def mno_zero_initialized_in_bss : Flag<["-"], "mno-zero-initialized-in-bss">, - HelpText<"Do not put zero initialized data in the BSS">; def mregparm : Separate<["-"], "mregparm">, HelpText<"Limit the number of registers available for integer arguments">; def msmall_data_limit : Separate<["-"], "msmall-data-limit">, ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] bb48005 - [NFC] Make AST_BLOCK_HASH test more robust with downstream changes
Author: Daniel Grumberg Date: 2020-06-19T09:41:15+01:00 New Revision: bb480056602daab86fbcd6aac5c6bc92ce350bb3 URL: https://github.com/llvm/llvm-project/commit/bb480056602daab86fbcd6aac5c6bc92ce350bb3 DIFF: https://github.com/llvm/llvm-project/commit/bb480056602daab86fbcd6aac5c6bc92ce350bb3.diff LOG: [NFC] Make AST_BLOCK_HASH test more robust with downstream changes Added: Modified: clang/test/Modules/ASTSignature.c Removed: diff --git a/clang/test/Modules/ASTSignature.c b/clang/test/Modules/ASTSignature.c index d041b61200a7..f0df1e4e7823 100644 --- a/clang/test/Modules/ASTSignature.c +++ b/clang/test/Modules/ASTSignature.c @@ -4,7 +4,7 @@ // RUN: -fmodules-cache-path=%t -fdisable-module-hash %s // RUN: cp %t/MyHeader2.pcm %t1.pcm // RUN: rm -rf %t -// RUN: %clang_cc1 -iquote "/dev/null" -iquote %S/Inputs/ASTHash/ -fsyntax-only \ +// RUN: %clang_cc1 -nostdinc++ -iquote %S/Inputs/ASTHash/ -fsyntax-only \ // RUN: -fmodules -fimplicit-module-maps -fmodules-strict-context-hash \ // RUN: -fmodules-cache-path=%t -fdisable-module-hash %s // RUN: cp %t/MyHeader2.pcm %t2.pcm ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 29125dd - Start adding support for generating CC1 command lines from CompilerInvocation
Author: Daniel Grumberg Date: 2020-06-24T18:05:05+01:00 New Revision: 29125ddf1323951901184d2859274afdecac0327 URL: https://github.com/llvm/llvm-project/commit/29125ddf1323951901184d2859274afdecac0327 DIFF: https://github.com/llvm/llvm-project/commit/29125ddf1323951901184d2859274afdecac0327.diff LOG: Start adding support for generating CC1 command lines from CompilerInvocation This change includes the following: - Add additional information in the relevant table-gen files to encode the necessary information to automatically parse the argument into a CompilerInvocation instance and to generate the appropriate command line argument from a CompilerInvocation instance. - Extend OptParserEmitter to emit the necessary macro tables as well as constant tables to support parsing and generating command line arguments for options that provide the necessary information. - Port some options to use this new system for parsing and generating command line arguments. Differential Revision: https://reviews.llvm.org/D79796 Added: clang/unittests/Frontend/CompilerInvocationTest.cpp Modified: clang/include/clang/Driver/CC1Options.td clang/include/clang/Frontend/CompilerInvocation.h clang/lib/Frontend/CompilerInvocation.cpp clang/unittests/Frontend/CMakeLists.txt llvm/include/llvm/Option/OptParser.td llvm/utils/TableGen/OptParserEmitter.cpp Removed: diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index cf2235ed9274..bc1fd0b58d3e 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -23,7 +23,9 @@ def target_cpu : Separate<["-"], "target-cpu">, def target_feature : Separate<["-"], "target-feature">, HelpText<"Target specific attributes">; def triple : Separate<["-"], "triple">, - HelpText<"Specify target triple (e.g. i686-apple-darwin9)">; + HelpText<"Specify target triple (e.g. i686-apple-darwin9)">, + MarshallingInfoString<"TargetOpts->Triple", "llvm::sys::getDefaultTargetTriple()", "std::string">, + AlwaysEmit, Normalizer<"normalizeTriple">, DenormalizeString; def target_abi : Separate<["-"], "target-abi">, HelpText<"Target a particular ABI type">; def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">, @@ -212,7 +214,11 @@ def msave_temp_labels : Flag<["-"], "msave-temp-labels">, "Note this may change .s semantics and shouldn't generally be used " "on compiler-generated code.">; def mrelocation_model : Separate<["-"], "mrelocation-model">, - HelpText<"The relocation model to use">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">; + HelpText<"The relocation model to use">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">, + NormalizedValuesScope<"llvm::Reloc">, + NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>, + MarshallingInfoString<"CodeGenOpts.RelocationModel", "PIC_", "Model">, + AutoNormalizeEnum; def fno_math_builtin : Flag<["-"], "fno-math-builtin">, HelpText<"Disable implicit builtin knowledge of math functions">; } @@ -837,7 +843,8 @@ def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">, HelpText<"Enable hashing the content of a module file">; def fmodules_strict_context_hash : Flag<["-"], "fmodules-strict-context-hash">, HelpText<"Enable hashing of all compiler options that could impact the " - "semantics of a module in an implicit build">; + "semantics of a module in an implicit build">, + MarshallingInfoFlag<"HeaderSearchOpts->ModulesStrictContextHash", "false">; def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"">, HelpText<"Add directory to the C SYSTEM include search path">; def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">, diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h index e63408da8f5e..c723fc084c85 100644 --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -153,6 +153,8 @@ class CompilerInvocation : public CompilerInvocationBase { /// one of the vaild-to-access (albeit arbitrary) states. /// /// \param [out] Res - The resulting invocation. + /// \param [in] CommandLineArgs - Array of argument strings, this must not + /// contain "-cc1". static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef CommandLineArgs, DiagnosticsEngine &Diags, @@ -184,6 +186,18 @@ class CompilerInvocation : public CompilerInvocationBase { /// identifying the conditions under which the module was built. std::string getModuleHash() const; + using StringAllocator = llvm::function_ref; + /// Generate a cc1-compatible command line arguments from this instance. + /// + /// \param [out] Args - The generated a
[clang] e4e2d8e - Ensure that CompilerInvocationTest normalizes default target triples
Author: Daniel Grumberg Date: 2020-06-25T10:41:40+01:00 New Revision: e4e2d8e4c2d2d61a5baf7eeab69a3f539343eca6 URL: https://github.com/llvm/llvm-project/commit/e4e2d8e4c2d2d61a5baf7eeab69a3f539343eca6 DIFF: https://github.com/llvm/llvm-project/commit/e4e2d8e4c2d2d61a5baf7eeab69a3f539343eca6.diff LOG: Ensure that CompilerInvocationTest normalizes default target triples This fixes a build failure. More details at http://lab.llvm.org:8011/builders/llvm-clang-win-x-armv7l/builds/78/steps/test-check-clang/logs/FAIL%3A%20Clang-Unit%3A%3ACC1CommandLineGenerationTest.CanGenerateCC1CommandLineSeparateRequiredAbsent Added: Modified: clang/unittests/Frontend/CompilerInvocationTest.cpp Removed: diff --git a/clang/unittests/Frontend/CompilerInvocationTest.cpp b/clang/unittests/Frontend/CompilerInvocationTest.cpp index 9cce66e41872..ed82d678462f 100644 --- a/clang/unittests/Frontend/CompilerInvocationTest.cpp +++ b/clang/unittests/Frontend/CompilerInvocationTest.cpp @@ -78,7 +78,8 @@ TEST_F(CC1CommandLineGenerationTest, TEST_F(CC1CommandLineGenerationTest, CanGenerateCC1CommandLineSeparateRequiredAbsent) { - const std::string DefaultTriple = llvm::sys::getDefaultTargetTriple(); + const std::string DefaultTriple = + llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); const char *Args[] = {"clang", "-xc++", "-"}; CompilerInvocation CInvok; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f79a66b - Ensure that default value for -triple is correctly normalizedvalues
Author: Daniel Grumberg Date: 2020-06-25T17:49:59+01:00 New Revision: f79a66ba69628db471d559f0f182f476bf49ac90 URL: https://github.com/llvm/llvm-project/commit/f79a66ba69628db471d559f0f182f476bf49ac90 DIFF: https://github.com/llvm/llvm-project/commit/f79a66ba69628db471d559f0f182f476bf49ac90.diff LOG: Ensure that default value for -triple is correctly normalizedvalues This fixes the build failure at http://lab.llvm.org:8011/builders/llvm-clang-win-x-aarch64/builds/240/steps/test-check-clang/logs/FAIL%3A%20Clang-Unit%3A%3ACC1CommandLineGenerationTest.CanGenerateCC1CommandLineSeparateRequiredAbsent Added: Modified: clang/include/clang/Driver/CC1Options.td Removed: diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index bc1fd0b58d3e..8729512454c3 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -24,7 +24,7 @@ def target_feature : Separate<["-"], "target-feature">, HelpText<"Target specific attributes">; def triple : Separate<["-"], "triple">, HelpText<"Specify target triple (e.g. i686-apple-darwin9)">, - MarshallingInfoString<"TargetOpts->Triple", "llvm::sys::getDefaultTargetTriple()", "std::string">, + MarshallingInfoString<"TargetOpts->Triple", "llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple())", "std::string">, AlwaysEmit, Normalizer<"normalizeTriple">, DenormalizeString; def target_abi : Separate<["-"], "target-abi">, HelpText<"Target a particular ABI type">; ___ 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 &Availabilities) { 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][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] 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] 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] [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" + }, + "pathCompon
[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] 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 &Block, + FunctionProtoTypeLoc &BlockProto, + DeclarationFragments &After); }; 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 &Block, + clang::FunctionProtoTypeLoc &BlockProto) { + 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 &DeclarationFragments::appendSpace() { if (!Fragments.empty()) { Fragment &Last = 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
[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] 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 &CI, return std::nullopt; } +std::optional getRelativeIncludeName(const CompilerInstance &CI, + 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, &IsQuoted)) +if (auto IncludeName = getRelativeIncludeName(CI, *File, &IsQuoted)) if (llvm::any_of(KnownFiles, [&IsQuoted, &IncludeName](const auto &KnownFile) { 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-
[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)
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)
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] Record availability information only for the target platform (PR #76823)
@@ -45,7 +45,7 @@ RecordTy *addTopLevelRecord(DenseMap &USRLookupTable, NamespaceRecord * APISet::addNamespace(APIRecord *Parent, StringRef Name, StringRef USR, - PresumedLoc Loc, AvailabilitySet Availability, + PresumedLoc Loc, const AvailabilityInfo &Availability, 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] 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 &Availability, LinkageInfo Linkage, const DocComment &Comment, 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)
@@ -256,14 +256,14 @@ struct APIRecord { APIRecord() = delete; APIRecord(RecordKind Kind, StringRef USR, StringRef Name, -PresumedLoc Location, AvailabilitySet Availabilities, +PresumedLoc Location, const AvailabilityInfo &Availability, 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] 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 &Comment, 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 &Comment, 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 &Comment, DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader); + DeclarationFragments SubHeading, APIRecord::RecordKind Kind, + bool IsFromSystemH
[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] 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] 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 &Comment, 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 &Comment, 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 &Comment, 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. /// /// No
[clang] 5ef2ec7 - [clang][extract-api] Suppprt for the module name property in SymbolGraph
Author: Daniel Grumberg Date: 2022-03-23T16:34:08Z New Revision: 5ef2ec7e4e129cb9a1d9e688fbf8590a85f01530 URL: https://github.com/llvm/llvm-project/commit/5ef2ec7e4e129cb9a1d9e688fbf8590a85f01530 DIFF: https://github.com/llvm/llvm-project/commit/5ef2ec7e4e129cb9a1d9e688fbf8590a85f01530.diff LOG: [clang][extract-api] Suppprt for the module name property in SymbolGraph Adds `--product-name=` flag to the clang driver. This gets forwarded to cc1 only when we are performing a ExtractAPI Action. This is used to populate the `name` field of the module object in the generated SymbolGraph. Differential Revision: https://reviews.llvm.org/D122141 Added: Modified: clang/include/clang/Driver/Options.td 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/ExtractAPIConsumer.cpp clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/test/ExtractAPI/global_record.c Removed: diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 41b3ca5a4583e..b5bd2d6c3e1bd 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1091,6 +1091,8 @@ def interface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version= def exported__symbols__list : Separate<["-"], "exported_symbols_list">; def extract_api : Flag<["-"], "extract-api">, Flags<[CC1Option]>, Group, HelpText<"Extract API information">; +def product_name_EQ: Joined<["--"], "product-name=">, Flags<[CC1Option]>, + 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/Serialization/SerializerBase.h b/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h index cec35987813f9..2bcf81a804b39 100644 --- a/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h +++ b/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h @@ -34,6 +34,12 @@ class APISerializer { protected: const APISet &API; + + /// The product name of API. + /// + /// Note: This should be used for populating metadata about the API. + StringRef ProductName; + APISerializerOption Options; public: @@ -44,8 +50,9 @@ class APISerializer { APISerializer &operator=(APISerializer &&) = delete; protected: - APISerializer(const APISet &API, APISerializerOption Options = {}) - : API(API), Options(Options) {} + APISerializer(const APISet &API, StringRef ProductName, +APISerializerOption Options = {}) + : API(API), ProductName(ProductName), Options(Options) {} virtual ~APISerializer() = default; }; diff --git a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h index 8fe5a34e5113d..11c84c1e205d6 100644 --- a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h +++ b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h @@ -90,8 +90,9 @@ class SymbolGraphSerializer : public APISerializer { void serializeGlobalRecord(const GlobalRecord &Record); public: - SymbolGraphSerializer(const APISet &API, APISerializerOption Options = {}) - : APISerializer(API, Options) {} + SymbolGraphSerializer(const APISet &API, StringRef ProductName, +APISerializerOption Options = {}) + : APISerializer(API, ProductName, Options) {} }; } // namespace extractapi diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 7ce8076a3ee41..db4da799481fa 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -410,6 +410,10 @@ class FrontendOptions { /// The name of the action to run when using a plugin action. std::string ActionName; + // Currently this is only used as part of the `-extract-api` action. + /// The name of the product the input files belong too. + std::string ProductName; + /// Args to pass to the plugins std::map> PluginArgs; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 2221ce5a07677..b9d36a753d072 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4641,6 +4641,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, assert(JA.getType() == types::TY_API_INFO && "Extract API actions must generate a API information."); CmdArgs.push_back("-extract-api"); +if (Arg *ProductNam
[clang] f833aab - [clang][extract-api] Enable processing of multiple headers
Author: Daniel Grumberg Date: 2022-03-23T19:05:19Z New Revision: f833aab0d0bf1bd9e9903a1398e429f431532f5f URL: https://github.com/llvm/llvm-project/commit/f833aab0d0bf1bd9e9903a1398e429f431532f5f DIFF: https://github.com/llvm/llvm-project/commit/f833aab0d0bf1bd9e9903a1398e429f431532f5f.diff LOG: [clang][extract-api] Enable processing of multiple headers Before actually executing the ExtractAPIAction, clear the CompilationInstance's input list and replace it with a single synthesized file that just includes (or imports in ObjC) all the inputs. Depends on D122141 Differential Revision: https://reviews.llvm.org/D122175 Added: clang/test/ExtractAPI/global_record_multifile.c Modified: clang/include/clang/ExtractAPI/FrontendActions.h clang/lib/ExtractAPI/ExtractAPIConsumer.cpp Removed: diff --git a/clang/include/clang/ExtractAPI/FrontendActions.h b/clang/include/clang/ExtractAPI/FrontendActions.h index e43b6cf9212d6..4c9449fe73a92 100644 --- a/clang/include/clang/ExtractAPI/FrontendActions.h +++ b/clang/include/clang/ExtractAPI/FrontendActions.h @@ -24,9 +24,22 @@ class ExtractAPIAction : public ASTFrontendAction { std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override; +private: + /// The synthesized input buffer that contains all the provided input header + /// files. + std::unique_ptr Buffer; + public: + /// Prepare to execute the action on the given CompilerInstance. + /// + /// This is called before executing the action on any inputs. This generates a + /// single header that includes all of CI's inputs and replaces CI's input + /// list with it before actually executing the action. + bool PrepareToExecuteAction(CompilerInstance &CI) override; + static std::unique_ptr CreateOutputFile(CompilerInstance &CI, StringRef InFile); + static StringRef getInputBufferName() { return ""; } }; } // namespace clang diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index 7007d08e839be..0636e6de7cc26 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -27,6 +27,9 @@ #include "clang/ExtractAPI/Serialization/SymbolGraphSerializer.h" #include "clang/Frontend/ASTConsumers.h" #include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendOptions.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -339,6 +342,35 @@ ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::move(OS)); } +bool ExtractAPIAction::PrepareToExecuteAction(CompilerInstance &CI) { + auto &Inputs = CI.getFrontendOpts().Inputs; + if (Inputs.empty()) +return true; + + auto Kind = Inputs[0].getKind(); + + // Convert the header file inputs into a single input buffer. + SmallString<256> HeaderContents; + for (const FrontendInputFile &FIF : Inputs) { +if (Kind.isObjectiveC()) + HeaderContents += "#import"; +else + HeaderContents += "#include"; +HeaderContents += " \""; +HeaderContents += FIF.getFile(); +HeaderContents += "\"\n"; + } + + Buffer = llvm::MemoryBuffer::getMemBufferCopy(HeaderContents, +getInputBufferName()); + + // Set that buffer up as our "real" input in the CompilerInstance. + Inputs.clear(); + Inputs.emplace_back(Buffer->getMemBufferRef(), Kind, /*IsSystem*/ false); + + return true; +} + std::unique_ptr ExtractAPIAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile) { std::unique_ptr OS = diff --git a/clang/test/ExtractAPI/global_record_multifile.c b/clang/test/ExtractAPI/global_record_multifile.c new file mode 100644 index 0..cc5448e838298 --- /dev/null +++ b/clang/test/ExtractAPI/global_record_multifile.c @@ -0,0 +1,371 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s@INPUT_DIR@%/t@g" %t/reference.output.json.in >> \ +// RUN: %t/reference.output.json +// RUN: %clang -extract-api --product-name=GlobalRecord -target arm64-apple-macosx \ +// RUN: %t/input1.h %t/input2.h %t/input3.h -o %t/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/output.json >> %t/output-normalized.json +// RUN: diff %t/reference.output.json %t/output-normalized.json + +// CHECK-NOT: error: +// CHECK-NOT: warning: + +//--- input1.h +int num; + +//--- input2.h +/** + * \brief Add two numbers. + * \param [in] x A number. + * \param [in] y Another number. + * \param [out] res The result of x + y. + */ +void add(const int x, const int y, int *res); + +//--- input3.h +char unavailable __attribute__((unavailable)
[clang] 0ee06c3 - [clang][extract-api] Stop allocating APIRecords via BumpPtrAllocator
Author: Daniel Grumberg Date: 2022-03-24T17:44:00Z New Revision: 0ee06c31aa57576c05c7ca3e68d2cac9ddf59811 URL: https://github.com/llvm/llvm-project/commit/0ee06c31aa57576c05c7ca3e68d2cac9ddf59811 DIFF: https://github.com/llvm/llvm-project/commit/0ee06c31aa57576c05c7ca3e68d2cac9ddf59811.diff LOG: [clang][extract-api] Stop allocating APIRecords via BumpPtrAllocator Using a BumpPtrAllocator introduced memory leaks for APIRecords as they contain a std::vector. This meant that we needed to always keep a reference to the records in APISet and arrange for their destructor to get called appropriately. This was further complicated by the need for records to own sub-records as these subrecords would still need to be allocated via the BumpPtrAllocator and the owning record would now need to arrange for the destructor of its subrecords to be called appropriately. Since APIRecords contain a std::vector so whenever elements get added to that there is an associated heap allocation regardless. Since performance isn't currently our main priority it makes sense to use regular unique_ptr to keep track of APIRecords, this way we don't need to arrange for destructors to get called. The BumpPtrAllocator is still used for strings such as USRs so that we can easily de-duplicate them as necessary. Differential Revision: https://reviews.llvm.org/D122331 Added: Modified: clang/include/clang/ExtractAPI/API.h clang/lib/ExtractAPI/API.cpp Removed: diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index e8f9219358ccf..beedda6464438 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -30,25 +30,6 @@ #include "llvm/Support/Casting.h" #include -namespace { - -/// \brief A custom deleter used for ``std::unique_ptr`` to APIRecords stored -/// in the BumpPtrAllocator. -/// -/// \tparam T the exact type of the APIRecord subclass. -template struct UniquePtrBumpPtrAllocatorDeleter { - void operator()(T *Instance) { Instance->~T(); } -}; - -/// A unique pointer to an APIRecord stored in the BumpPtrAllocator. -/// -/// \tparam T the exact type of the APIRecord subclass. -template -using APIRecordUniquePtr = -std::unique_ptr>; - -} // anonymous namespace - namespace clang { namespace extractapi { @@ -165,7 +146,7 @@ struct EnumConstantRecord : APIRecord { /// This holds information associated with enums. struct EnumRecord : APIRecord { - SmallVector> Constants; + SmallVector> Constants; EnumRecord(StringRef Name, StringRef USR, PresumedLoc Loc, const AvailabilityInfo &Availability, const DocComment &Comment, @@ -194,7 +175,7 @@ struct StructFieldRecord : APIRecord { /// This holds information associated with structs. struct StructRecord : APIRecord { - SmallVector> Fields; + SmallVector> Fields; StructRecord(StringRef Name, StringRef USR, PresumedLoc Loc, const AvailabilityInfo &Availability, const DocComment &Comment, @@ -302,17 +283,16 @@ class APISet { /// A map to store the set of GlobalRecord%s with the declaration name as the /// key. using GlobalRecordMap = - llvm::MapVector>; + llvm::MapVector>; /// A map to store the set of EnumRecord%s with the declaration name as the /// key. - using EnumRecordMap = - llvm::MapVector>; + using EnumRecordMap = llvm::MapVector>; /// A map to store the set of StructRecord%s with the declaration name as the /// key. using StructRecordMap = - llvm::MapVector>; + llvm::MapVector>; /// Get the target triple for the ExtractAPI invocation. const llvm::Triple &getTarget() const { return Target; } @@ -340,8 +320,10 @@ class APISet { : Target(Target), LangOpts(LangOpts) {} private: - /// BumpPtrAllocator to store APIRecord%s and generated/copied strings. - llvm::BumpPtrAllocator Allocator; + /// BumpPtrAllocator to store generated/copied strings. + /// + /// Note: The main use for this is being able to deduplicate strings. + llvm::BumpPtrAllocator StringAllocator; const llvm::Triple Target; const LangOptions LangOpts; diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp index 7aa82336ee2ca..6b60d2c2a1b42 100644 --- a/clang/lib/ExtractAPI/API.cpp +++ b/clang/lib/ExtractAPI/API.cpp @@ -17,7 +17,7 @@ #include "clang/AST/CommentLexer.h" #include "clang/AST/RawCommentList.h" #include "clang/Index/USRGeneration.h" -#include "llvm/Support/Allocator.h" +#include using namespace clang::extractapi; using namespace llvm; @@ -32,9 +32,9 @@ GlobalRecord *APISet::addGlobal(GVKind Kind, StringRef Name, StringRef USR, auto Result = Globals.insert({Name, nullptr}); if (Result.second) { // Create the record if it does not already exist. -auto Record = APIRecordUniquePtr(new (Allocator) GlobalRecord{ +auto Record = std::make_unique(
[clang] a9909d2 - [clang][extractapi] Tie API and serialization to the FrontendAction
Author: Daniel Grumberg Date: 2022-03-30T18:32:58+01:00 New Revision: a9909d23e9bb8c4649cba1c14d479c28df4ca185 URL: https://github.com/llvm/llvm-project/commit/a9909d23e9bb8c4649cba1c14d479c28df4ca185 DIFF: https://github.com/llvm/llvm-project/commit/a9909d23e9bb8c4649cba1c14d479c28df4ca185.diff LOG: [clang][extractapi] Tie API and serialization to the FrontendAction Make the API records a property of the action instead of the ASTVisitor so that it can be accessed outside the AST visitation and push back serialization to the end of the frontend action. This will allow accessing and modifying the API records outside of the ASTVisitor, which is a prerequisite for supporting macros. Added: Modified: clang/include/clang/ExtractAPI/FrontendActions.h clang/lib/ExtractAPI/ExtractAPIConsumer.cpp Removed: diff --git a/clang/include/clang/ExtractAPI/FrontendActions.h b/clang/include/clang/ExtractAPI/FrontendActions.h index 4c9449fe73a92..2bdb61dc6994d 100644 --- a/clang/include/clang/ExtractAPI/FrontendActions.h +++ b/clang/include/clang/ExtractAPI/FrontendActions.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H #define LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H +#include "clang/ExtractAPI/API.h" #include "clang/Frontend/FrontendAction.h" namespace clang { @@ -25,11 +26,19 @@ class ExtractAPIAction : public ASTFrontendAction { StringRef InFile) override; private: + /// A representation of the APIs this action extracts. + std::unique_ptr API; + + /// A stream to the output file of this action. + std::unique_ptr OS; + + /// The product this action is extracting API information for. + std::string ProductName; + /// The synthesized input buffer that contains all the provided input header /// files. std::unique_ptr Buffer; -public: /// Prepare to execute the action on the given CompilerInstance. /// /// This is called before executing the action on any inputs. This generates a @@ -37,8 +46,15 @@ class ExtractAPIAction : public ASTFrontendAction { /// list with it before actually executing the action. bool PrepareToExecuteAction(CompilerInstance &CI) override; + /// Called after executing the action on the synthesized input buffer. + /// + /// Note: Now that we have gathered all the API definitions to surface we can + /// emit them in this callback. + void EndSourceFileAction() override; + static std::unique_ptr CreateOutputFile(CompilerInstance &CI, StringRef InFile); + static StringRef getInputBufferName() { return ""; } }; diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index bcc01dbd710d8..10b28873611e9 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -41,8 +41,8 @@ namespace { /// information. class ExtractAPIVisitor : public RecursiveASTVisitor { public: - ExtractAPIVisitor(ASTContext &Context, Language Lang) - : Context(Context), API(Context.getTargetInfo().getTriple(), Lang) {} + ExtractAPIVisitor(ASTContext &Context, APISet &API) + : Context(Context), API(API) {} const APISet &getAPI() const { return API; } @@ -489,43 +489,40 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { } ASTContext &Context; - APISet API; + APISet &API; }; class ExtractAPIConsumer : public ASTConsumer { public: - ExtractAPIConsumer(ASTContext &Context, StringRef ProductName, Language Lang, - std::unique_ptr OS) - : Visitor(Context, Lang), ProductName(ProductName), OS(std::move(OS)) {} + ExtractAPIConsumer(ASTContext &Context, APISet &API) + : Visitor(Context, API) {} void HandleTranslationUnit(ASTContext &Context) override { // Use ExtractAPIVisitor to traverse symbol declarations in the context. Visitor.TraverseDecl(Context.getTranslationUnitDecl()); - -// Setup a SymbolGraphSerializer to write out collected API information in -// the Symbol Graph format. -// FIXME: Make the kind of APISerializer configurable. -SymbolGraphSerializer SGSerializer(Visitor.getAPI(), ProductName); -SGSerializer.serialize(*OS); } private: ExtractAPIVisitor Visitor; - std::string ProductName; - std::unique_ptr OS; }; } // namespace std::unique_ptr ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - std::unique_ptr OS = CreateOutputFile(CI, InFile); + OS = CreateOutputFile(CI, InFile); if (!OS) return nullptr; - return std::make_unique( - CI.getASTContext(), CI.getInvocation().getFrontendOpts().ProductName, - CI.getFrontendOpts().Inputs.back().getKind().getLanguage(), - std::move(OS)); + + ProductName = CI.getFrontendOpts().ProductName; + + // Now that we have enough information about the language options and the + //
[clang] 529a057 - [clang][extract-api] Add support for macros
Author: Daniel Grumberg Date: 2022-03-30T18:33:10+01:00 New Revision: 529a0570f7e8c5144bd3ad057e43f00e3af58d1b URL: https://github.com/llvm/llvm-project/commit/529a0570f7e8c5144bd3ad057e43f00e3af58d1b DIFF: https://github.com/llvm/llvm-project/commit/529a0570f7e8c5144bd3ad057e43f00e3af58d1b.diff LOG: [clang][extract-api] Add support for macros To achieve this we hook into the preprocessor during the ExtractAPIAction and record definitions for macros that don't get undefined during preprocessing. Added: clang/test/ExtractAPI/macro_undefined.c clang/test/ExtractAPI/macros.c Modified: clang/include/clang/ExtractAPI/API.h clang/include/clang/ExtractAPI/DeclarationFragments.h clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h clang/lib/ExtractAPI/API.cpp clang/lib/ExtractAPI/DeclarationFragments.cpp 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 57397e7c256ea..142dd7a45de47 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -30,6 +30,7 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" #include +#include namespace clang { namespace extractapi { @@ -49,6 +50,9 @@ namespace extractapi { /// \endcode using DocComment = std::vector; +// Classes deriving from APIRecord need to have Name be the first constructor +// argument. This is so that they are compatible with `addTopLevelRecord` +// defined in API.cpp /// The base representation of an API record. Holds common symbol information. struct APIRecord { StringRef Name; @@ -83,6 +87,7 @@ struct APIRecord { RK_ObjCMethod, RK_ObjCInterface, RK_ObjCProtocol, +RK_MacroDefinition, }; private: @@ -119,10 +124,11 @@ struct GlobalRecord : APIRecord { /// The function signature of the record if it is a function. FunctionSignature Signature; - GlobalRecord(GVKind Kind, StringRef Name, StringRef USR, PresumedLoc Loc, + GlobalRecord(StringRef Name, StringRef USR, PresumedLoc Loc, const AvailabilityInfo &Availability, LinkageInfo Linkage, const DocComment &Comment, DeclarationFragments Declaration, - DeclarationFragments SubHeading, FunctionSignature Signature) + DeclarationFragments SubHeading, GVKind Kind, + FunctionSignature Signature) : APIRecord(RK_Global, Name, USR, Loc, Availability, Linkage, Comment, Declaration, SubHeading), GlobalKind(Kind), Signature(Signature) {} @@ -374,6 +380,21 @@ struct ObjCProtocolRecord : ObjCContainerRecord { virtual void anchor(); }; +struct MacroDefinitionRecord : APIRecord { + MacroDefinitionRecord(StringRef Name, StringRef USR, PresumedLoc Loc, +DeclarationFragments Declaration, +DeclarationFragments SubHeading) + : APIRecord(RK_MacroDefinition, Name, USR, Loc, AvailabilityInfo(), + LinkageInfo(), {}, Declaration, SubHeading) {} + + static bool classof(const APIRecord *Record) { +return Record->getKind() == RK_MacroDefinition; + } + +private: + virtual void anchor(); +}; + /// APISet holds the set of API records collected from given inputs. class APISet { public: @@ -530,29 +551,24 @@ class APISet { DeclarationFragments Declaration, DeclarationFragments SubHeading); - /// A map to store the set of GlobalRecord%s with the declaration name as the - /// key. - using GlobalRecordMap = - llvm::MapVector>; - - /// A map to store the set of EnumRecord%s with the declaration name as the - /// key. - using EnumRecordMap = llvm::MapVector>; - - /// A map to store the set of StructRecord%s with the declaration name as the - /// key. - using StructRecordMap = - llvm::MapVector>; - - /// A map to store the set of ObjCInterfaceRecord%s with the declaration name - /// as the key. - using ObjCInterfaceRecordMap = - llvm::MapVector>; - - /// A map to store the set of ObjCProtocolRecord%s with the declaration name - /// as the key. - using ObjCProtocolRecordMap = - llvm::MapVector>; + /// Create a macro definition 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::recordUSRForMacro(StringRef Name, + /// SourceLocation SL, const SourceManager &SM) is a helper method to generate + /// the USR for the macro and keep it alive in APISet. + MacroDefinitionRecord *addMacroDefinition(StringRef Name, StringRef USR, +Pre
[clang] 985eaa1 - [clang][extract-api][NFC] Don't remap the generated input buffer in PPOpts
Author: Daniel Grumberg Date: 2022-03-30T20:38:09+01:00 New Revision: 985eaa1a3da2a1b88ea70a65ffd5783aa82ea65e URL: https://github.com/llvm/llvm-project/commit/985eaa1a3da2a1b88ea70a65ffd5783aa82ea65e DIFF: https://github.com/llvm/llvm-project/commit/985eaa1a3da2a1b88ea70a65ffd5783aa82ea65e.diff LOG: [clang][extract-api][NFC] Don't remap the generated input buffer in PPOpts This was triggering some build failures so removing this change for now. Added: Modified: clang/lib/ExtractAPI/ExtractAPIConsumer.cpp Removed: diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index 266acff9a72ef..cf95c3d739b60 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -617,17 +617,13 @@ bool ExtractAPIAction::PrepareToExecuteAction(CompilerInstance &CI) { HeaderContents += "\"\n"; } - auto Buffer = llvm::MemoryBuffer::getMemBufferCopy(HeaderContents, - getInputBufferName()); + Buffer = llvm::MemoryBuffer::getMemBufferCopy(HeaderContents, +getInputBufferName()); // Set that buffer up as our "real" input in the CompilerInstance. Inputs.clear(); Inputs.emplace_back(Buffer->getMemBufferRef(), Kind, /*IsSystem*/ false); - // Tell the processor about the input file. - CI.getPreprocessorOpts().addRemappedFile(Buffer->getBufferIdentifier(), - Buffer.release()); - return true; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 422d05e - [clang][extract-api][NFC] Add documentation
Author: Daniel Grumberg Date: 2022-04-04T18:59:44+01:00 New Revision: 422d05e792dbd6a97f5afd4cdd5e8aa677e97444 URL: https://github.com/llvm/llvm-project/commit/422d05e792dbd6a97f5afd4cdd5e8aa677e97444 DIFF: https://github.com/llvm/llvm-project/commit/422d05e792dbd6a97f5afd4cdd5e8aa677e97444.diff LOG: [clang][extract-api][NFC] Add documentation Add struct level documentation for MacroDefinitionRecord. Differential Revision: https://reviews.llvm.org/D122798 Added: Modified: clang/include/clang/ExtractAPI/API.h Removed: diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index 142dd7a45de47..62e30b1d4c57b 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -380,6 +380,7 @@ struct ObjCProtocolRecord : ObjCContainerRecord { virtual void anchor(); }; +/// This holds information associated with macro definitions. struct MacroDefinitionRecord : APIRecord { MacroDefinitionRecord(StringRef Name, StringRef USR, PresumedLoc Loc, DeclarationFragments Declaration, ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 8b63622 - [clang][extract-api] Undefining macros should not result in a crash
Author: Daniel Grumberg Date: 2022-04-05T11:42:45+01:00 New Revision: 8b63622b9fd9ad2a86487da6098b7a4351d3e8eb URL: https://github.com/llvm/llvm-project/commit/8b63622b9fd9ad2a86487da6098b7a4351d3e8eb DIFF: https://github.com/llvm/llvm-project/commit/8b63622b9fd9ad2a86487da6098b7a4351d3e8eb.diff LOG: [clang][extract-api] Undefining macros should not result in a crash This fixes the situation where a undefining a not previously defined macro resulted in a crash. Before trying to remove a definition from PendingMacros we first check to see if the macro did indeed have a previous definition. Differential Revision: https://reviews.llvm.org/D123056 Added: Modified: clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/test/ExtractAPI/macro_undefined.c Removed: diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index cf95c3d739b60..e4ae0403f260f 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -534,6 +534,11 @@ class MacroCallback : public PPCallbacks { // macro definition for it. void MacroUndefined(const Token &MacroNameToken, const MacroDefinition &MD, const MacroDirective *Undef) override { +// If this macro wasn't previously defined we don't need to do anything +// here. +if (!Undef) + return; + llvm::erase_if(PendingMacros, [&MD](const PendingMacro &PM) { return MD.getMacroInfo()->getDefinitionLoc() == PM.MD->getMacroInfo()->getDefinitionLoc(); diff --git a/clang/test/ExtractAPI/macro_undefined.c b/clang/test/ExtractAPI/macro_undefined.c index e04712500ef93..f128a446b6588 100644 --- a/clang/test/ExtractAPI/macro_undefined.c +++ b/clang/test/ExtractAPI/macro_undefined.c @@ -19,6 +19,8 @@ FUNC_GEN(foo) FUNC_GEN(bar, const int *, unsigned); #undef FUNC_GEN +// Undefining a not previously defined macro should not result in a crash. +#undef FOO //--- reference.output.json.in { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 28d7931 - [clang][extract-api] Fix small issues with SymbolGraphSerializer
Author: Daniel Grumberg Date: 2022-04-06T18:42:55+01:00 New Revision: 28d793144f2a5c92b83df3cc3d2772ec4cab0ad3 URL: https://github.com/llvm/llvm-project/commit/28d793144f2a5c92b83df3cc3d2772ec4cab0ad3 DIFF: https://github.com/llvm/llvm-project/commit/28d793144f2a5c92b83df3cc3d2772ec4cab0ad3.diff LOG: [clang][extract-api] Fix small issues with SymbolGraphSerializer This includes: - replacing "relationhips" with "relationships" - emitting the "pathComponents" property on symbols - emitting the "accessLevel" property on symbols Differential Revision: https://reviews.llvm.org/D123045 Added: Modified: clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/test/ExtractAPI/enum.c clang/test/ExtractAPI/global_record.c clang/test/ExtractAPI/global_record_multifile.c clang/test/ExtractAPI/language.c clang/test/ExtractAPI/macro_undefined.c clang/test/ExtractAPI/macros.c clang/test/ExtractAPI/objc_interface.m clang/test/ExtractAPI/objc_protocol.m clang/test/ExtractAPI/struct.c Removed: diff --git a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h index 02ea9c2e92c83..7b55fd788f6d0 100644 --- a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h +++ b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h @@ -19,6 +19,7 @@ #include "clang/ExtractAPI/API.h" #include "clang/ExtractAPI/Serialization/SerializerBase.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/JSON.h" #include "llvm/Support/VersionTuple.h" #include "llvm/Support/raw_ostream.h" @@ -45,6 +46,25 @@ class SymbolGraphSerializer : public APISerializer { /// The Symbol Graph format version used by this serializer. static const VersionTuple FormatVersion; + using PathComponentStack = llvm::SmallVector; + /// The current path component stack. + /// + /// Note: this is used to serialize the ``pathComponents`` field of symbols in + /// the Symbol Graph. + PathComponentStack PathComponents; + + /// A helper type to manage PathComponents correctly using RAII. + struct PathComponentGuard { +PathComponentGuard(PathComponentStack &PC, StringRef Component) : PC(PC) { + PC.emplace_back(Component); +} + +~PathComponentGuard() { PC.pop_back(); } + + private: +PathComponentStack &PC; + }; + public: /// Serialize the APIs in \c APISet in the Symbol Graph format. /// @@ -126,6 +146,13 @@ class SymbolGraphSerializer : public APISerializer { /// Serialize a macro defintion record. void serializeMacroDefinitionRecord(const MacroDefinitionRecord &Record); + /// Push a component to the current path components stack. + /// + /// \param Component The component to push onto the path components stack. + /// \return A PathComponentGuard responsible for removing the latest + /// component from the stack on scope exit. + LLVM_NODISCARD PathComponentGuard makePathComponentGuard(StringRef Component); + public: SymbolGraphSerializer(const APISet &API, StringRef ProductName, APISerializerOption Options = {}) diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index bfd2c207c0918..1440ca358d4b5 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -90,27 +90,35 @@ Object serializePlatform(const Triple &T) { return Platform; } +/// Serialize a source position. +Object serializeSourcePosition(const PresumedLoc &Loc) { + assert(Loc.isValid() && "invalid source position"); + + Object SourcePosition; + SourcePosition["line"] = Loc.getLine(); + SourcePosition["character"] = Loc.getColumn(); + + return SourcePosition; +} + /// Serialize a source location in file. /// /// \param Loc The presumed location to serialize. /// \param IncludeFileURI If true, include the file path of \p Loc as a URI. /// Defaults to false. -Object serializeSourcePosition(const PresumedLoc &Loc, +Object serializeSourceLocation(const PresumedLoc &Loc, bool IncludeFileURI = false) { - assert(Loc.isValid() && "invalid source position"); - - Object SourcePosition; - SourcePosition["line"] = Loc.getLine(); - SourcePosition["character"] = Loc.getColumn(); + Object SourceLocation; + serializeObject(SourceLocation, "position", serializeSourcePosition(Loc)); if (IncludeFileURI) { std::string FileURI = "file://"; // Normalize file path to use forward slashes for the URI. FileURI += sys::path::convert_to_slash(Loc.getFilename()); -SourcePosition["uri"] = FileURI; +SourceLocation["uri"] = FileURI; } - return SourcePosi
[clang] 9fc45ca - [clang][extract-api] Add support for typedefs
Author: Daniel Grumberg Date: 2022-04-06T19:14:05+01:00 New Revision: 9fc45ca00a19336c0724631aa1b1985dd4f4d536 URL: https://github.com/llvm/llvm-project/commit/9fc45ca00a19336c0724631aa1b1985dd4f4d536 DIFF: https://github.com/llvm/llvm-project/commit/9fc45ca00a19336c0724631aa1b1985dd4f4d536.diff LOG: [clang][extract-api] Add support for typedefs Typedef records consist of the symbol associated with the underlying TypedefDecl and a SymbolReference to the underlying type. Additionally typedefs for anonymous TagTypes use the typedef'd name as the symbol name in their respective records and USRs. As a result the declaration fragments for the anonymous TagType are those for the associated typedef. This means that when the user is defining a typedef to a typedef to a anonymous type, we use a reference the anonymous TagType itself and do not emit the typedef to the anonymous type in the generated symbol graph, including in the type destination of further typedef symbol records. Differential Revision: https://reviews.llvm.org/D123019 Added: clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.h clang/test/ExtractAPI/typedef.c clang/test/ExtractAPI/typedef_anonymous_record.c clang/test/ExtractAPI/typedef_chain.c Modified: clang/include/clang/ExtractAPI/API.h clang/include/clang/ExtractAPI/DeclarationFragments.h clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h clang/lib/ExtractAPI/API.cpp clang/lib/ExtractAPI/CMakeLists.txt clang/lib/ExtractAPI/DeclarationFragments.cpp 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 62e30b1d4c57b..827cde953c31c 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -88,6 +88,7 @@ struct APIRecord { RK_ObjCInterface, RK_ObjCProtocol, RK_MacroDefinition, +RK_Typedef, }; private: @@ -396,6 +397,30 @@ struct MacroDefinitionRecord : APIRecord { virtual void anchor(); }; +/// This holds information associated with typedefs. +/// +/// Note: Typedefs for anonymous enums and structs typically don't get emitted +/// by the serializers but still get a TypedefRecord. Instead we use the +/// typedef name as a name for the underlying anonymous struct or enum. +struct TypedefRecord : APIRecord { + SymbolReference UnderlyingType; + + TypedefRecord(StringRef Name, StringRef USR, PresumedLoc Loc, +const AvailabilityInfo &Availability, const DocComment &Comment, +DeclarationFragments Declaration, +DeclarationFragments SubHeading, SymbolReference UnderlyingType) + : APIRecord(RK_Typedef, Name, USR, Loc, Availability, LinkageInfo(), + Comment, Declaration, SubHeading), +UnderlyingType(UnderlyingType) {} + + static bool classof(const APIRecord *Record) { +return Record->getKind() == RK_Typedef; + } + +private: + virtual void anchor(); +}; + /// APISet holds the set of API records collected from given inputs. class APISet { public: @@ -564,6 +589,19 @@ class APISet { DeclarationFragments Declaration, DeclarationFragments SubHeading); + /// Create a typedef 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. + TypedefRecord *addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc, +const AvailabilityInfo &Availability, +const DocComment &Comment, +DeclarationFragments Declaration, +DeclarationFragments SubHeading, +SymbolReference UnderlyingType); + /// A mapping type to store a set of APIRecord%s with the declaration name as /// the key. template &getMacros() const { return Macros; } + const RecordMap &getTypedefs() const { return Typedefs; } /// Generate and store the USR of declaration \p D. /// @@ -626,6 +665,7 @@ class APISet { RecordMap ObjCInterfaces; RecordMap ObjCProtocols; RecordMap Macros; + RecordMap Typedefs; }; } // namespace extractapi diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h b/clang/include/clang/ExtractAPI/DeclarationFragments.h index 7f6e3311125aa..80fb5faf68783 100644 --- a/clang/include/clang/ExtractAPI/DeclarationFragments.h +++ b/clang/include/clang/ExtractAPI/DeclarationFragment
[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
[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 &Record, Language Lang) { Kind["displayName"] = "Instance Variable"; break; case APIRecord::RK_ObjCMethod: -if (dyn_cast(&Record)->IsInstanceMethod) { +if (cast(&Record)->IsInstanceMethod) { Kind["identifier"] = AddLangPrefix("method"); Kind["displayName"] = "Instance Method"; } else { @@ -360,8 +360,13 @@ Object serializeSymbolKind(const APIRecord &Record, Language Lang) { } break; case APIRecord::RK_ObjCProperty: -Kind["identifier"] = AddLangPrefix("property"); -Kind["displayName"] = "Instance Property"; +if (cast(&Record)->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": " " +}, +
[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] fc35376 - Ensure that APIRecords get destroyed correctly.
Author: Daniel Grumberg Date: 2022-03-19T00:49:37Z New Revision: fc3537697db7724834d8071cfee10cacceb9fc2a URL: https://github.com/llvm/llvm-project/commit/fc3537697db7724834d8071cfee10cacceb9fc2a DIFF: https://github.com/llvm/llvm-project/commit/fc3537697db7724834d8071cfee10cacceb9fc2a.diff LOG: Ensure that APIRecords get destroyed correctly. Implements an APISet specific unique ptr type that has a custom deleter that just calls the underlying APIRecord subclass destructor. Added: Modified: clang/include/clang/SymbolGraph/API.h clang/lib/SymbolGraph/API.cpp clang/test/SymbolGraph/global_record.c Removed: diff --git a/clang/include/clang/SymbolGraph/API.h b/clang/include/clang/SymbolGraph/API.h index 541673f36b223..ffcc03758f4d2 100644 --- a/clang/include/clang/SymbolGraph/API.h +++ b/clang/include/clang/SymbolGraph/API.h @@ -24,6 +24,7 @@ #include "llvm/ADT/Triple.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" +#include namespace clang { namespace symbolgraph { @@ -120,7 +121,25 @@ class APISet { StringRef copyString(StringRef String, llvm::BumpPtrAllocator &Allocator); StringRef copyString(StringRef String); - using GlobalRecordMap = llvm::MapVector; +private: + /// \brief A custom deleter used for ``std::unique_ptr`` to APIRecords stored + /// in the BumpPtrAllocator. + /// + /// \tparam T the exact type of the APIRecord subclass. + template struct UniquePtrBumpPtrAllocatorDeleter { +void operator()(T *Instance) { Instance->~T(); } + }; + +public: + /// A unique pointer to an APIRecord stored in the BumpPtrAllocator. + /// + /// \tparam T the exact type of the APIRecord subclass. + template + using APIRecordUniquePtr = + std::unique_ptr>; + + using GlobalRecordMap = + llvm::MapVector>; const GlobalRecordMap &getGlobals() const { return Globals; } diff --git a/clang/lib/SymbolGraph/API.cpp b/clang/lib/SymbolGraph/API.cpp index 4066428c97fc9..69e7469425c98 100644 --- a/clang/lib/SymbolGraph/API.cpp +++ b/clang/lib/SymbolGraph/API.cpp @@ -32,12 +32,12 @@ GlobalRecord *APISet::addGlobal(GVKind Kind, StringRef Name, StringRef USR, FunctionSignature Signature) { auto Result = Globals.insert({Name, nullptr}); if (Result.second) { -GlobalRecord *Record = new (Allocator) -GlobalRecord{Kind,Name,USR, Loc,Availability, - Linkage, Comment, Fragments, SubHeading, Signature}; -Result.first->second = Record; +auto Record = APIRecordUniquePtr(new (Allocator) GlobalRecord{ +Kind, Name, USR, Loc, Availability, Linkage, Comment, Fragments, +SubHeading, Signature}); +Result.first->second = std::move(Record); } - return Result.first->second; + return Result.first->second.get(); } GlobalRecord * diff --git a/clang/test/SymbolGraph/global_record.c b/clang/test/SymbolGraph/global_record.c index c1baaf260fd10..fa577ee29b17d 100644 --- a/clang/test/SymbolGraph/global_record.c +++ b/clang/test/SymbolGraph/global_record.c @@ -1,5 +1,3 @@ -// FIXME: disable the test to unblock build bots -// UNSUPPORTED: true // RUN: rm -rf %t // RUN: split-file %s %t // RUN: sed -e "s@INPUT_DIR@%/t@g" %t/reference.output.json.in >> \ ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] edbb99a - Ensure -extract-api handles multiple headers correctly
Author: Daniel Grumberg Date: 2022-03-21T21:04:47Z New Revision: edbb99a7edc6f2dca0ebb27d95c624aa6479eb21 URL: https://github.com/llvm/llvm-project/commit/edbb99a7edc6f2dca0ebb27d95c624aa6479eb21 DIFF: https://github.com/llvm/llvm-project/commit/edbb99a7edc6f2dca0ebb27d95c624aa6479eb21.diff LOG: Ensure -extract-api handles multiple headers correctly clang -extract-api should accept multiple headers and forward them to a single CC1 instance. This change introduces a new ExtractAPIJobAction. Currently API Extraction is done during the Precompile phase as this is the current phase that matches the requirements the most. Adding a new phase would need to change some logic in how phases are scheduled. If the headers scheduled for API extraction are of different types the driver emits a diagnostic. Differential Revision: https://reviews.llvm.org/D121936 Added: clang/test/Driver/extract-api-multiheader-kind-diag.h clang/test/Driver/extract-api-multiheader.h clang/test/Driver/extract-api.h Modified: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Driver/Action.h clang/include/clang/Driver/Types.def clang/lib/Driver/Action.cpp clang/lib/Driver/Driver.cpp clang/lib/Driver/ToolChain.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/test/SymbolGraph/global_record.c Removed: clang/test/Driver/extract-api.c diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 0a62d4b85c9d1..59862555cc8f6 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -464,6 +464,10 @@ def err_test_module_file_extension_format : Error< "-ftest-module-file-extension argument '%0' is not of the required form " "'blockname:major:minor:hashed:user info'">; +def err_drv_extract_api_wrong_kind : Error< + "header file '%0' input '%1' does not match the type of prior input " + "in api extraction; use '-x %2' to override">; + def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">, InGroup>; def note_use_dashdash : Note< diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h index 458a10ee11274..36410150c2797 100644 --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -59,6 +59,7 @@ class Action { PreprocessJobClass, PrecompileJobClass, HeaderModulePrecompileJobClass, +ExtractAPIJobClass, AnalyzeJobClass, MigrateJobClass, CompileJobClass, @@ -443,6 +444,19 @@ class HeaderModulePrecompileJobAction : public PrecompileJobAction { const char *getModuleName() const { return ModuleName; } }; +class ExtractAPIJobAction : public JobAction { + void anchor() override; + +public: + ExtractAPIJobAction(Action *Input, types::ID OutputType); + + static bool classof(const Action *A) { +return A->getKind() == ExtractAPIJobClass; + } + + void addHeaderInput(Action *Input) { getInputs().push_back(Input); } +}; + class AnalyzeJobAction : public JobAction { void anchor() override; diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def index 7adf59ca5c992..7e38417a84a66 100644 --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -100,5 +100,5 @@ TYPE("dSYM", dSYM, INVALID, "dSYM", phases TYPE("dependencies", Dependencies, INVALID, "d", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("cuda-fatbin", CUDA_FATBIN, INVALID, "fatbin", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("hip-fatbin", HIP_FATBIN, INVALID, "hipfb", phases::Compile, phases::Backend, phases::Assemble, phases::Link) -TYPE("api-information", API_INFO, INVALID, "json", phases::Compile) +TYPE("api-information", API_INFO, INVALID, "json", phases::Precompile) TYPE("none", Nothing, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link) diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp index eb08bfe9cde56..21691c4ac4b98 100644 --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -26,6 +26,8 @@ const char *Action::getClassName(ActionClass AC) { case PreprocessJobClass: return "preprocessor"; case PrecompileJobClass: return "precompiler"; case HeaderModulePrecompileJobClass: return "header-module-precompiler"; + case ExtractAPIJobClass: +return "api-extractor"; case AnalyzeJobClass: return "analyzer"; case MigrateJobClass: return "migrator"; case CompileJobClass: return "compiler"; @@ -339,6 +341,11 @@ HeaderModulePrecompileJobAction::HeaderModulePrecompileJ
[clang] aebe5fc - [clang][extract-api] Process only APIs declared in inputs
Author: Daniel Grumberg Date: 2022-04-07T17:49:05+01:00 New Revision: aebe5fc6e7d8ab99f3796067d430752552932d28 URL: https://github.com/llvm/llvm-project/commit/aebe5fc6e7d8ab99f3796067d430752552932d28 DIFF: https://github.com/llvm/llvm-project/commit/aebe5fc6e7d8ab99f3796067d430752552932d28.diff LOG: [clang][extract-api] Process only APIs declared in inputs We should only process APIs declared in the command line inputs to avoid drowning the ExtractAPI output with symbols the user doesn't care about. This is achieved by keeping track of the provided input files and checking that the associated Decl or Macro is declared in one of those files. Differential Revision: https://reviews.llvm.org/D123148 Added: clang/test/ExtractAPI/known_files_only.c clang/test/ExtractAPI/known_files_only_hmap.c Modified: clang/include/clang/ExtractAPI/FrontendActions.h clang/lib/ExtractAPI/ExtractAPIConsumer.cpp Removed: diff --git a/clang/include/clang/ExtractAPI/FrontendActions.h b/clang/include/clang/ExtractAPI/FrontendActions.h index 2bdb61dc6994d..dec3b5ca93d18 100644 --- a/clang/include/clang/ExtractAPI/FrontendActions.h +++ b/clang/include/clang/ExtractAPI/FrontendActions.h @@ -39,6 +39,9 @@ class ExtractAPIAction : public ASTFrontendAction { /// files. std::unique_ptr Buffer; + /// The input file originally provided on the command line. + std::vector KnownInputFiles; + /// Prepare to execute the action on the given CompilerInstance. /// /// This is called before executing the action on any inputs. This generates a diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index 7c2914da7ea0c..949413d7d2b1d 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -20,6 +20,8 @@ #include "clang/AST/ParentMapContext.h" #include "clang/AST/RawCommentList.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/ExtractAPI/API.h" #include "clang/ExtractAPI/AvailabilityInfo.h" @@ -31,11 +33,15 @@ #include "clang/Frontend/FrontendOptions.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" +#include +#include using namespace clang; using namespace extractapi; @@ -49,12 +55,44 @@ StringRef getTypedefName(const TagDecl *Decl) { return {}; } +struct LocationFileChecker { + bool isLocationInKnownFile(SourceLocation Loc) { +// If the loc refers to a macro expansion we need to first get the file +// location of the expansion. +auto FileLoc = SM.getFileLoc(Loc); +FileID FID = SM.getFileID(FileLoc); +if (FID.isInvalid()) + return false; + +const auto *File = SM.getFileEntryForID(FID); +if (!File) + return false; + +if (KnownFileEntries.count(File)) + return true; + +return false; + } + + LocationFileChecker(const SourceManager &SM, + const std::vector &KnownFiles) + : SM(SM) { +for (const auto &KnownFilePath : KnownFiles) + if (auto FileEntry = SM.getFileManager().getFile(KnownFilePath)) +KnownFileEntries.insert(*FileEntry); + } + +private: + const SourceManager &SM; + llvm::DenseSet KnownFileEntries; +}; + /// The RecursiveASTVisitor to traverse symbol declarations and collect API /// information. class ExtractAPIVisitor : public RecursiveASTVisitor { public: - ExtractAPIVisitor(ASTContext &Context, APISet &API) - : Context(Context), API(API) {} + ExtractAPIVisitor(ASTContext &Context, LocationFileChecker &LCF, APISet &API) + : Context(Context), API(API), LCF(LCF) {} const APISet &getAPI() const { return API; } @@ -76,6 +114,9 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { Decl->getTemplateSpecializationKind() == TSK_Undeclared) return true; +if (!LCF.isLocationInKnownFile(Decl->getLocation())) + return true; + // Collect symbol information. StringRef Name = Decl->getName(); StringRef USR = API.recordUSR(Decl); @@ -133,6 +174,9 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { return true; } +if (!LCF.isLocationInKnownFile(Decl->getLocation())) + return true; + // Collect symbol information. StringRef Name = Decl->getName(); StringRef USR = API.recordUSR(Decl); @@ -167,6 +211,9 @@ class ExtractAPIVisitor : public RecursiveASTVisitor { if (!Decl->isThisDeclarationADefinition()) return true; +if (!LCF.isLocationInKnownFile(Decl->getLocation())) +
[clang] 1015592 - [clang][extract-api][NFC] Use dedicated API to check for macro equality
Author: Daniel Grumberg Date: 2022-04-07T19:08:17+01:00 New Revision: 101559225189e63b7f6236fb944501b1e6b74a87 URL: https://github.com/llvm/llvm-project/commit/101559225189e63b7f6236fb944501b1e6b74a87 DIFF: https://github.com/llvm/llvm-project/commit/101559225189e63b7f6236fb944501b1e6b74a87.diff LOG: [clang][extract-api][NFC] Use dedicated API to check for macro equality Differential Revision: https://reviews.llvm.org/D123295 Added: Modified: clang/lib/ExtractAPI/ExtractAPIConsumer.cpp Removed: diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index 949413d7d2b1d..0757881862984 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -649,8 +649,9 @@ class ExtractAPIConsumer : public ASTConsumer { class MacroCallback : public PPCallbacks { public: - MacroCallback(const SourceManager &SM, LocationFileChecker &LCF, APISet &API) - : SM(SM), LCF(LCF), API(API) {} + MacroCallback(const SourceManager &SM, LocationFileChecker &LCF, APISet &API, +Preprocessor &PP) + : SM(SM), LCF(LCF), API(API), PP(PP) {} void MacroDefined(const Token &MacroNameToken, const MacroDirective *MD) override { @@ -677,9 +678,9 @@ class MacroCallback : public PPCallbacks { if (!Undef) return; -llvm::erase_if(PendingMacros, [&MD](const PendingMacro &PM) { - return MD.getMacroInfo()->getDefinitionLoc() == - PM.MD->getMacroInfo()->getDefinitionLoc(); +llvm::erase_if(PendingMacros, [&MD, this](const PendingMacro &PM) { + return MD.getMacroInfo()->isIdenticalTo(*PM.MD->getMacroInfo(), PP, + /*Syntactically*/ false); }); } @@ -719,6 +720,7 @@ class MacroCallback : public PPCallbacks { const SourceManager &SM; LocationFileChecker &LCF; APISet &API; + Preprocessor &PP; llvm::SmallVector PendingMacros; }; @@ -741,9 +743,8 @@ ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { auto LCF = std::make_unique(CI.getSourceManager(), KnownInputFiles); - // Register preprocessor callbacks that will add macro definitions to API. - CI.getPreprocessor().addPPCallbacks( - std::make_unique(CI.getSourceManager(), *LCF, *API)); + CI.getPreprocessor().addPPCallbacks(std::make_unique( + CI.getSourceManager(), *LCF, *API, CI.getPreprocessor())); return std::make_unique(CI.getASTContext(), std::move(LCF), *API); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 80ae366 - [clang][extract-api] Emit "navigator" property of "name" in SymbolGraph
Author: Daniel Grumberg Date: 2022-04-08T17:29:00+01:00 New Revision: 80ae366592924c8a32f81f96b316595ec90ec672 URL: https://github.com/llvm/llvm-project/commit/80ae366592924c8a32f81f96b316595ec90ec672 DIFF: https://github.com/llvm/llvm-project/commit/80ae366592924c8a32f81f96b316595ec90ec672.diff LOG: [clang][extract-api] Emit "navigator" property of "name" in SymbolGraph Differential Revision: https://reviews.llvm.org/D123391 Added: Modified: clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/test/ExtractAPI/enum.c clang/test/ExtractAPI/global_record.c clang/test/ExtractAPI/global_record_multifile.c clang/test/ExtractAPI/known_files_only.c clang/test/ExtractAPI/known_files_only_hmap.c clang/test/ExtractAPI/language.c clang/test/ExtractAPI/macro_undefined.c clang/test/ExtractAPI/macros.c clang/test/ExtractAPI/objc_category.m clang/test/ExtractAPI/objc_interface.m clang/test/ExtractAPI/objc_protocol.m clang/test/ExtractAPI/struct.c clang/test/ExtractAPI/typedef.c clang/test/ExtractAPI/typedef_anonymous_record.c clang/test/ExtractAPI/typedef_chain.c Removed: diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index efe3c276671da..2a3818e0da520 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -14,6 +14,7 @@ #include "clang/ExtractAPI/Serialization/SymbolGraphSerializer.h" #include "clang/Basic/Version.h" #include "clang/ExtractAPI/API.h" +#include "clang/ExtractAPI/DeclarationFragments.h" #include "llvm/Support/JSON.h" #include "llvm/Support/Path.h" #include "llvm/Support/VersionTuple.h" @@ -331,6 +332,12 @@ Object serializeNames(const APIRecord &Record) { Names["title"] = Record.Name; serializeArray(Names, "subHeading", serializeDeclarationFragments(Record.SubHeading)); + DeclarationFragments NavigatorFragments; + NavigatorFragments.append(Record.Name, +DeclarationFragments::FragmentKind::Identifier, +/*PreciseIdentifier*/ ""); + serializeArray(Names, "navigator", + serializeDeclarationFragments(NavigatorFragments)); return Names; } diff --git a/clang/test/ExtractAPI/enum.c b/clang/test/ExtractAPI/enum.c index a9646e21cc8f1..60f69059c942f 100644 --- a/clang/test/ExtractAPI/enum.c +++ b/clang/test/ExtractAPI/enum.c @@ -161,6 +161,12 @@ enum Direction : unsigned char { "uri": "file://INPUT_DIR/input.h" }, "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "Vehicle" + } +], "subHeading": [ { "kind": "identifier", @@ -197,6 +203,12 @@ enum Direction : unsigned char { "uri": "file://INPUT_DIR/input.h" }, "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "Bicycle" + } +], "subHeading": [ { "kind": "identifier", @@ -234,6 +246,12 @@ enum Direction : unsigned char { "uri": "file://INPUT_DIR/input.h" }, "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "Car" + } +], "subHeading": [ { "kind": "identifier", @@ -288,6 +306,12 @@ enum Direction : unsigned char { "uri": "file://INPUT_DIR/input.h" }, "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "Train" + } +], "subHeading": [ { "kind": "identifier", @@ -325,6 +349,12 @@ enum Direction : unsigned char { "uri": "file://INPUT_DIR/input.h" }, "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "Ship" + } +], "subHeading": [ { "kind": "identifier", @@ -362,6 +392,12 @@ enum Direction : unsigned char { "uri": "file://INPUT_DIR/input.h" }, "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "Airplane" + } +], "subHeading": [ { "kind": "identifier", @@ -416,6 +452,12 @@ enum Direction : unsigned char { "uri": "file://INPUT_DIR/input.h" }, "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "Direction" + } +], "subHeading": [ { "kind": "identifier", @@ -452,6 +494,12 @@ enum Direction : unsigned char { "ur
[clang] 236b6a0 - [clang][extract-api] Emit "functionSignature" in SGF for ObjC methods.
Author: Daniel Grumberg Date: 2022-04-11T19:05:24+01:00 New Revision: 236b6a0eb41a163510e65664e2160f599287326b URL: https://github.com/llvm/llvm-project/commit/236b6a0eb41a163510e65664e2160f599287326b DIFF: https://github.com/llvm/llvm-project/commit/236b6a0eb41a163510e65664e2160f599287326b.diff LOG: [clang][extract-api] Emit "functionSignature" in SGF for ObjC methods. - Split GlobalRecord into two distinct types to be able to introduce has_function_signature type trait. - Add has_function_signature type trait. - Serialize function signatures as part of serializeAPIRecord for records that are known to have a function signature. Differential Revision: https://reviews.llvm.org/D123304 Added: Modified: clang/include/clang/ExtractAPI/API.h clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h clang/lib/ExtractAPI/API.cpp clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp clang/test/ExtractAPI/objc_category.m clang/test/ExtractAPI/objc_interface.m Removed: diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index 57b6a2ee5a43c..6a9429704d45e 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -77,7 +77,8 @@ struct APIRecord { /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.) enum RecordKind { -RK_Global, +RK_GlobalFunction, +RK_GlobalVariable, RK_EnumConstant, RK_Enum, RK_StructField, @@ -112,31 +113,40 @@ struct APIRecord { virtual ~APIRecord() = 0; }; -/// The kind of a global record. -enum class GVKind : uint8_t { - Unknown = 0, - Variable = 1, - Function = 2, -}; +/// This holds information associated with global functions. +struct GlobalFunctionRecord : APIRecord { + FunctionSignature Signature; -/// This holds information associated with global variables or functions. -struct GlobalRecord : APIRecord { - GVKind GlobalKind; + GlobalFunctionRecord(StringRef Name, StringRef USR, PresumedLoc Loc, + const AvailabilityInfo &Availability, + LinkageInfo Linkage, const DocComment &Comment, + DeclarationFragments Declaration, + DeclarationFragments SubHeading, + FunctionSignature Signature) + : APIRecord(RK_GlobalFunction, Name, USR, Loc, Availability, Linkage, + Comment, Declaration, SubHeading), +Signature(Signature) {} - /// The function signature of the record if it is a function. - FunctionSignature Signature; + static bool classof(const APIRecord *Record) { +return Record->getKind() == RK_GlobalFunction; + } - GlobalRecord(StringRef Name, StringRef USR, PresumedLoc Loc, - const AvailabilityInfo &Availability, LinkageInfo Linkage, - const DocComment &Comment, DeclarationFragments Declaration, - DeclarationFragments SubHeading, GVKind Kind, - FunctionSignature Signature) - : APIRecord(RK_Global, Name, USR, Loc, Availability, Linkage, Comment, - Declaration, SubHeading), -GlobalKind(Kind), Signature(Signature) {} +private: + virtual void anchor(); +}; + +/// This holds information associated with global functions. +struct GlobalVariableRecord : APIRecord { + GlobalVariableRecord(StringRef Name, StringRef USR, PresumedLoc Loc, + const AvailabilityInfo &Availability, + LinkageInfo Linkage, const DocComment &Comment, + DeclarationFragments Declaration, + DeclarationFragments SubHeading) + : APIRecord(RK_GlobalVariable, Name, USR, Loc, Availability, Linkage, + Comment, Declaration, SubHeading) {} static bool classof(const APIRecord *Record) { -return Record->getKind() == RK_Global; +return Record->getKind() == RK_GlobalVariable; } private: @@ -446,33 +456,31 @@ struct TypedefRecord : APIRecord { virtual void anchor(); }; +/// Check if a record type has a function signature mixin. +/// +/// This is denoted by the record type having a ``Signature`` field of type +/// FunctionSignature. +template +struct has_function_signature : public std::false_type {}; +template <> +struct has_function_signature : public std::true_type {}; +template <> +struct has_function_signature : public std::true_type {}; + /// APISet holds the set of API records collected from given inputs. class APISet { public: - /// Create and add a GlobalRecord of kind \p Kind 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 generat
[clang] 7443a50 - [clang][extract-api] Add support for true anonymous enums
Author: Daniel Grumberg Date: 2022-04-12T20:42:17+01:00 New Revision: 7443a504bf6c22b83727c1e43c82c4165b2d5db5 URL: https://github.com/llvm/llvm-project/commit/7443a504bf6c22b83727c1e43c82c4165b2d5db5 DIFF: https://github.com/llvm/llvm-project/commit/7443a504bf6c22b83727c1e43c82c4165b2d5db5.diff LOG: [clang][extract-api] Add support for true anonymous enums Anonymous enums without a typedef should have a "(anonymous)" identifier. Differential Revision: https://reviews.llvm.org/D123533 Added: Modified: clang/include/clang/ExtractAPI/API.h clang/lib/ExtractAPI/API.cpp clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/test/ExtractAPI/enum.c Removed: diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index 6a9429704d45e..53db46ca44c13 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -50,13 +50,13 @@ namespace extractapi { /// \endcode using DocComment = std::vector; -// Classes deriving from APIRecord need to have Name be the first constructor +// Classes deriving from APIRecord need to have USR be the first constructor // argument. This is so that they are compatible with `addTopLevelRecord` // defined in API.cpp /// The base representation of an API record. Holds common symbol information. struct APIRecord { - StringRef Name; StringRef USR; + StringRef Name; PresumedLoc Location; AvailabilityInfo Availability; LinkageInfo Linkage; @@ -101,11 +101,11 @@ struct APIRecord { APIRecord() = delete; - APIRecord(RecordKind Kind, StringRef Name, StringRef USR, + APIRecord(RecordKind Kind, StringRef USR, StringRef Name, PresumedLoc Location, const AvailabilityInfo &Availability, LinkageInfo Linkage, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading) - : Name(Name), USR(USR), Location(Location), Availability(Availability), + : USR(USR), Name(Name), Location(Location), Availability(Availability), Linkage(Linkage), Comment(Comment), Declaration(Declaration), SubHeading(SubHeading), Kind(Kind) {} @@ -117,13 +117,13 @@ struct APIRecord { struct GlobalFunctionRecord : APIRecord { FunctionSignature Signature; - GlobalFunctionRecord(StringRef Name, StringRef USR, PresumedLoc Loc, + GlobalFunctionRecord(StringRef USR, StringRef Name, PresumedLoc Loc, const AvailabilityInfo &Availability, LinkageInfo Linkage, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, FunctionSignature Signature) - : APIRecord(RK_GlobalFunction, Name, USR, Loc, Availability, Linkage, + : APIRecord(RK_GlobalFunction, USR, Name, Loc, Availability, Linkage, Comment, Declaration, SubHeading), Signature(Signature) {} @@ -137,12 +137,12 @@ struct GlobalFunctionRecord : APIRecord { /// This holds information associated with global functions. struct GlobalVariableRecord : APIRecord { - GlobalVariableRecord(StringRef Name, StringRef USR, PresumedLoc Loc, + GlobalVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc, const AvailabilityInfo &Availability, LinkageInfo Linkage, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading) - : APIRecord(RK_GlobalVariable, Name, USR, Loc, Availability, Linkage, + : APIRecord(RK_GlobalVariable, USR, Name, Loc, Availability, Linkage, Comment, Declaration, SubHeading) {} static bool classof(const APIRecord *Record) { @@ -155,12 +155,12 @@ struct GlobalVariableRecord : APIRecord { /// This holds information associated with enum constants. struct EnumConstantRecord : APIRecord { - EnumConstantRecord(StringRef Name, StringRef USR, PresumedLoc Loc, + EnumConstantRecord(StringRef USR, StringRef Name, PresumedLoc Loc, const AvailabilityInfo &Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading) - : APIRecord(RK_EnumConstant, Name, USR, Loc, Availability, + : APIRecord(RK_EnumConstant, USR, Name, Loc, Availability, LinkageInfo::none(), Comment, Declaration, SubHeading) {} static bool classof(const APIRecord *Record) { @@ -175,10 +175,10 @@ struct EnumConstantRecord : APIRecord { struct EnumRecord : APIRecord { SmallVector> Constants; - EnumRecord(StringRef Name, StringRef USR, PresumedLoc Loc, + EnumRecord(StringRef USR, StringRef Name, PresumedLoc Loc, const AvailabilityInfo &Availability, const DocCom
[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] 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] 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)
@@ -119,20 +78,12 @@ static void WalkupFromMostDerivedType(LibClangExtractAPIVisitor &Visitor, 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)
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)
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] 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)
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] 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] 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] 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, TypedefResolver.g
[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] 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] 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 &Comment, 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 &Comment, 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 &Comment, 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
[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] 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] 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 &SourceMgr) { +/// \returns The locations that are relevant when searching for Doc comments +/// related to \p D. +static SmallVector +getDeclLocsForCommentSearch(const Decl *D, SourceManager &SourceMgr) { 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
[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 &SourceMgr) { +/// \returns The locations that are relevant when searching for Doc comments +/// related to \p D. +static SmallVector +getDeclLocsForCommentSearch(const Decl *D, SourceManager &SourceMgr) { 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
[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 &SourceMgr) { +/// \returns The locations that are relevant when searching for Doc comments +/// related to \p D. +static SmallVector +getDeclLocsForCommentSearch(const Decl *D, SourceManager &SourceMgr) { 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
[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] 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 &os) 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 &FM); + + APIIgnoresList() = default; + + /// Check if \p SymbolName is specified in the APIIgnoresList and if it should
[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 &Availability, +PresumedLoc Location, AvailabilitySet Availabilities, LinkageInfo Linkage, const DocComment &Comment, 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 &Availability, - LinkageInfo Linkage, const DocComment &Comment, + AvailabilitySet Availabilities, LinkageInfo Linkage, + const DocComment &Comment, 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 &Availability, - LinkageInfo Linkage, const DocComment &Comment, + AvailabilitySet Availabilities, LinkageInfo Linkage, + const DocComment &Comment, 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 &Availability, - const DocComment &Comment, + AvailabilitySet Availabilities, const DocComment &Comment,
[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": [ +"Vehi
[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 &getMacros() const { return Macros; } const RecordMap &getTypedefs() 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 &Records) { + 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", - "targe
[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": "c:@Ea@Constant
[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 &getMacros() const { return Macros; } const RecordMap &getTypedefs() 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 &Records) { - 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
[clang] 504736c - [clang][extract-api] Don't emit symbols prefixed with an underscore
Author: Daniel Grumberg Date: 2022-05-25T19:02:18+01:00 New Revision: 504736cedff39d46fffc1293a35602ba140b19a8 URL: https://github.com/llvm/llvm-project/commit/504736cedff39d46fffc1293a35602ba140b19a8 DIFF: https://github.com/llvm/llvm-project/commit/504736cedff39d46fffc1293a35602ba140b19a8.diff LOG: [clang][extract-api] Don't emit symbols prefixed with an underscore These symbols are understood to not be used for client API consumption by convention so they should not appear in the generated symbol graph. Differential Revision: https://reviews.llvm.org/D125678 Added: clang/test/ExtractAPI/underscored.c 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 045d5d68e733b..39d885c7c90aa 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -467,6 +467,11 @@ bool SymbolGraphSerializer::shouldSkip(const APIRecord &Record) const { if (Record.Availability.isUnconditionallyUnavailable()) return true; + // Filter out symbols prefixed with an underscored as they are understood to + // be symbols clients should not use. + if (Record.Name.startswith("_")) +return true; + return false; } diff --git a/clang/test/ExtractAPI/underscored.c b/clang/test/ExtractAPI/underscored.c new file mode 100644 index 0..47f1893cdb029 --- /dev/null +++ b/clang/test/ExtractAPI/underscored.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 +// expected-no-diagnostics + +// Global record +int _HiddenGlobal; +int exposed_global; + +// Record type +struct _HiddenRecord { + int a; +}; + +struct ExposedRecord { + int a; +}; + +// Typedef +typedef struct {} _HiddenTypedef; +typedef int ExposedTypedef; +typedef _HiddenTypedef ExposedTypedefToHidden; + +// Macros +#define _HIDDEN_MACRO 5 +#define EXPOSED_MACRO 5 + +// Symbols that start with '_' should not appear in the reference output +//--- 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@ExposedRecord@FI@a", + "target": "c:@S@ExposedRecord" +} + ], + "symbols": [ +{ + "accessLevel": "public", + "declarationFragments": [ +{ + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" +}, +{ + "kind": "text", + "spelling": " " +}, +{ + "kind": "identifier", + "spelling": "exposed_global" +} + ], + "identifier": { +"interfaceLanguage": "c", +"precise": "c:@exposed_global" + }, + "kind": { +"displayName": "Global Variable", +"identifier": "c.var" + }, + "location": { +"position": { + "character": 5, + "line": 5 +}, +"uri": "file://INPUT_DIR/input.h" + }, + "names": { +"navigator": [ + { +"kind": "identifier", +"spelling": "exposed_global" + } +], +"subHeading": [ + { +"kind": "identifier", +"spelling": "exposed_global" + } +], +"title": "exposed_global" + }, + "pathComponents": [ +"exposed_global" + ] +}, +{ + "accessLevel": "public", + "declarationFragments": [ +{ + "kind": "keyword", + "spelling": "struct" +}, +{ + "kind": "text", + "spelling": " " +}, +{ + "kind": "identifier", + "spelling": "ExposedRecord" +} + ], + "identifier": { +"interfaceLanguage": "c", +"precise": "c:@S@ExposedRecord" + }, + "kind": { +"displayNam
[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 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][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)
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 &SourceMgr) { +/// \returns The locations that are relevant when searching for Doc comments +/// related to \p D. +static SmallVector +getDeclLocsForCommentSearch(const Decl *D, SourceManager &SourceMgr) { 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, a
[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)
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)
@@ -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)
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 &SourceMgr) { +/// \returns The locations that are relevant when searching for Doc comments +/// related to \p D. +static SmallVector +getDeclLocsForCommentSearch(const Decl *D, SourceManager &SourceMgr) { 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 de
[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 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] 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": "id
[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 &Context, -llvm::unique_function LocationChecker, -APISet &API) - : Context(Context), API(API), -LocationChecker(std::move(LocationChecker)) {} + ExtractAPIVisitorBase(ASTContext &Context, APISet &API) + : Context(Context), API(API) {} const APISet &getAPI() 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 &Context; APISet &API; - 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 &getConcrete() { 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.ge
[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] 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 &Context, APISet &API) : Context(Context), API(API) {} +public: const APISet &getAPI() const { return API; } bool VisitVarDecl(const VarDecl *Decl); @@ -99,7 +100,9 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { } private: - Derived &getConcrete() { return *static_cast(this); } + Derived &getDerivedExtractAPIVisitor() { +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
[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 &Context, APISet &API) - : Context(Context), API(API) {} +/// The RecursiveASTVisitor to traverse symbol declarations and collect API +/// information. +class ExtractAPIVisitor : public RecursiveASTVisitor { public: + ExtractAPIVisitor(ASTContext &Context, +llvm::unique_function LocationChecker, +APISet &API) + : Context(Context), API(API), +LocationChecker(std::move(LocationChecker)) {} + const APISet &getAPI() 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 &Context; APISet &API; - - 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 &getDerivedExtractAPIVisitor() { -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:
[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 &Context, -llvm::unique_function LocationChecker, -APISet &API) - : Context(Context), API(API), -LocationChecker(std::move(LocationChecker)) {} +template +class ExtractAPIVisitorBase : public RecursiveASTVisitor { +protected: + ExtractAPIVisitorBase(ASTContext &Context, APISet &API) + : Context(Context), API(API) {} +public: const APISet &getAPI() 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 &Context; APISet &API; - 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 &getDerivedExtractAPIVisitor() { +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 fra
[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 &Record, const APISet &API, 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: "parentContexts":[{"kind":"objective-c.protocol","name
[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 &Availabilities) { for (const auto &AvailInfo : 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 https://lists.llvm.org/cg
[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 &Context, -llvm::unique_function LocationChecker, -APISet &API) - : Context(Context), API(API), -LocationChecker(std::move(LocationChecker)) {} +template +class ExtractAPIVisitorBase : public RecursiveASTVisitor { +protected: + ExtractAPIVisitorBase(ASTContext &Context, APISet &API) + : Context(Context), API(API) {} +public: const APISet &getAPI() 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 &Context; APISet &API; - 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 &getDerivedExtractAPIVisitor() { +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();