[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
This commit is contained in:
Daniel Grumberg
2022-04-01 19:14:23 +01:00
parent 482fad4a3f
commit 9fc45ca00a
13 changed files with 815 additions and 4 deletions

View File

@@ -408,6 +408,11 @@ Object serializeSymbolKind(const APIRecord &Record, Language Lang) {
case APIRecord::RK_MacroDefinition:
Kind["identifier"] = AddLangPrefix("macro");
Kind["displayName"] = "Macro";
break;
case APIRecord::RK_Typedef:
Kind["identifier"] = AddLangPrefix("typealias");
Kind["displayName"] = "Type Alias";
break;
}
return Kind;
@@ -618,6 +623,27 @@ void SymbolGraphSerializer::serializeMacroDefinitionRecord(
Symbols.emplace_back(std::move(*Macro));
}
void SymbolGraphSerializer::serializeTypedefRecord(
const TypedefRecord &Record) {
// Typedefs of anonymous types have their entries unified with the underlying
// type.
bool ShouldDrop = Record.UnderlyingType.Name.empty();
// enums declared with `NS_OPTION` have a named enum and a named typedef, with
// the same name
ShouldDrop |= (Record.UnderlyingType.Name == Record.Name);
if (ShouldDrop)
return;
auto TypedefPathComponentGuard = makePathComponentGuard(Record.Name);
auto Typedef = serializeAPIRecord(Record);
if (!Typedef)
return;
(*Typedef)["type"] = Record.UnderlyingType.USR;
Symbols.emplace_back(std::move(*Typedef));
}
SymbolGraphSerializer::PathComponentGuard
SymbolGraphSerializer::makePathComponentGuard(StringRef Component) {
return PathComponentGuard(PathComponents, Component);
@@ -651,6 +677,9 @@ Object SymbolGraphSerializer::serialize() {
for (const auto &Macro : API.getMacros())
serializeMacroDefinitionRecord(*Macro.second);
for (const auto &Typedef : API.getTypedefs())
serializeTypedefRecord(*Typedef.second);
Root["symbols"] = std::move(Symbols);
Root["relationships"] = std::move(Relationships);