Skip to content

Commit

Permalink
feat: support emitting USRs for other kinds of declarations (#3268)
Browse files Browse the repository at this point in the history
  • Loading branch information
zrlk committed Nov 19, 2018
1 parent b00ad21 commit 4d705cf
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 4 deletions.
17 changes: 17 additions & 0 deletions kythe/cxx/indexer/cxx/IndexerASTHooks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2060,6 +2060,7 @@ bool IndexerASTVisitor::VisitVarDecl(const clang::VarDecl* Decl) {
AddChildOfEdgeToDeclContext(Decl, DeclNode);
std::vector<LibrarySupport::Completion> Completions;
if (!IsDefinition(Decl)) {
AssignUSR(BodyDeclNode, Decl);
Observer.recordVariableNode(
BodyDeclNode, GraphObserver::Completeness::Incomplete,
GraphObserver::VariableSubkind::None, absl::nullopt);
Expand Down Expand Up @@ -2098,6 +2099,7 @@ bool IndexerASTVisitor::VisitVarDecl(const clang::VarDecl* Decl) {
Completions.push_back(LibrarySupport::Completion{NextDecl, TargetDecl});
}
}
AssignUSR(BodyDeclNode, Decl);
Observer.recordVariableNode(
BodyDeclNode, GraphObserver::Completeness::Definition,
GraphObserver::VariableSubkind::None, absl::nullopt);
Expand Down Expand Up @@ -2180,6 +2182,7 @@ bool IndexerASTVisitor::VisitFieldDecl(const clang::FieldDecl* Decl) {
Observer.recordVariableNode(DeclNode, GraphObserver::Completeness::Definition,
GraphObserver::VariableSubkind::Field,
Marks.GenerateMarkedSource(DeclNode));
AssignUSR(DeclNode, Decl);
if (const auto* TSI = Decl->getTypeSourceInfo()) {
// TODO(zarko): Record storage classes for fields.
AscribeSpelledType(TSI->getTypeLoc(), Decl->getType(), DeclNode);
Expand All @@ -2205,6 +2208,7 @@ bool IndexerASTVisitor::VisitEnumConstantDecl(
MaybeRecordDefinitionRange(
RangeInCurrentContext(Decl->isImplicit(), DeclNode, NameRange), DeclNode,
absl::nullopt);
AssignUSR(DeclNode, Decl);
Observer.recordIntegerConstantNode(DeclNode, Decl->getInitVal());
AddChildOfEdgeToDeclContext(Decl, DeclNode);
Observer.recordMarkedSource(DeclNode, Marks.GenerateMarkedSource(DeclNode));
Expand Down Expand Up @@ -2243,6 +2247,7 @@ bool IndexerASTVisitor::VisitEnumDecl(const clang::EnumDecl* Decl) {
if (Decl->getDefinition() != Decl) {
// TODO(jdennett): Should we use Type::isIncompleteType() instead of doing
// something enum-specific here?
AssignUSR(DeclNode, Decl);
Observer.recordEnumNode(
DeclNode,
HasSpecifiedStorageType ? GraphObserver::Completeness::Complete
Expand All @@ -2267,6 +2272,7 @@ bool IndexerASTVisitor::VisitEnumDecl(const clang::EnumDecl* Decl) {
}
}
}
AssignUSR(DeclNode, Decl);
Observer.recordEnumNode(DeclNode, GraphObserver::Completeness::Definition,
Decl->isScoped() ? GraphObserver::EnumKind::Scoped
: GraphObserver::EnumKind::Unscoped);
Expand Down Expand Up @@ -2703,6 +2709,7 @@ bool IndexerASTVisitor::VisitRecordDecl(const clang::RecordDecl* Decl) {
// there is a subtle difference.
// TODO(zarko): Add edges to previous decls.
if (Decl->getDefinition() != Decl) {
AssignUSR(BodyDeclNode, Decl);
Observer.recordRecordNode(BodyDeclNode, RK,
GraphObserver::Completeness::Incomplete,
absl::nullopt);
Expand Down Expand Up @@ -2745,6 +2752,7 @@ bool IndexerASTVisitor::VisitRecordDecl(const clang::RecordDecl* Decl) {
}
}
}
AssignUSR(BodyDeclNode, Decl);
Observer.recordRecordNode(
BodyDeclNode, RK, GraphObserver::Completeness::Definition, absl::nullopt);
Observer.recordMarkedSource(DeclNode, Marks.GenerateMarkedSource(DeclNode));
Expand Down Expand Up @@ -3066,6 +3074,7 @@ IndexerASTVisitor::BuildNodeIdForTypedefNameDecl(
auto Marks = MarkedSources.Generate(Decl);
Marks.set_implicit(Job->UnderneathImplicitTemplateInstantiation);
GraphObserver::NameId AliasNameId(BuildNameIdForDecl(Decl));
AssignUSR(AliasNameId, AliasedTypeId.value(), Decl);
return Observer.recordTypeAliasNode(
AliasNameId, AliasedTypeId.value(),
BuildNodeIdForType(FollowAliasChain(Decl)),
Expand Down Expand Up @@ -3141,6 +3150,7 @@ bool IndexerASTVisitor::VisitCTypedef(const clang::TypedefNameDecl* Decl) {
RangeInCurrentContext(Decl->isImplicit(), OuterNodeId, Range),
OuterNodeId, absl::nullopt);
AddChildOfEdgeToDeclContext(Decl, OuterNodeId);
AssignUSR(OuterNodeId, Decl);
}
return true;
}
Expand Down Expand Up @@ -4224,6 +4234,7 @@ NodeSet IndexerASTVisitor::BuildNodeSetForTypedef(clang::TypedefTypeLoc TL) {
// Or is always using the cached id sufficient?
NodeId ID = Observer.nodeIdForTypeAliasNode(AliasID, *AliasedTypeID);
auto Marks = MarkedSources.Generate(TL.getTypedefNameDecl());
AssignUSR(ID, TL.getTypedefNameDecl());
return Observer.recordTypeAliasNode(
ID, *AliasedTypeID,
BuildNodeIdForType(FollowAliasChain(TL.getTypedefNameDecl())),
Expand Down Expand Up @@ -4620,6 +4631,7 @@ bool IndexerASTVisitor::VisitObjCCompatibleAliasDecl(
AliasID, AliasedTypeID, AliasedTypeID,
Marks.GenerateMarkedSource(
Observer.nodeIdForTypeAliasNode(AliasID, AliasedTypeID)));
AssignUSR(AliasID, AliasedTypeID, Decl);

// Record the definition of this type alias
MaybeRecordDefinitionRange(ExplicitRangeInCurrentContext(AliasRange),
Expand Down Expand Up @@ -4663,6 +4675,7 @@ bool IndexerASTVisitor::VisitObjCImplementationDecl(
} else {
LogErrorWithASTDump("Missing class interface", ImplDecl);
}
AssignUSR(DeclNode, ImplDecl);
Observer.recordRecordNode(DeclNode, GraphObserver::RecordKind::Class,
GraphObserver::Completeness::Definition,
Marks.GenerateMarkedSource(DeclNode));
Expand All @@ -4689,6 +4702,7 @@ bool IndexerASTVisitor::VisitObjCCategoryImplDecl(
FileID ImplDeclFile =
Observer.getSourceManager()->getFileID(ImplDecl->getCategoryNameLoc());

AssignUSR(ImplDeclNode, ImplDecl);
Observer.recordRecordNode(ImplDeclNode, GraphObserver::RecordKind::Category,
GraphObserver::Completeness::Definition,
Marks.GenerateMarkedSource(ImplDeclNode));
Expand Down Expand Up @@ -4854,6 +4868,7 @@ bool IndexerASTVisitor::VisitObjCInterfaceDecl(
auto Completeness = IsObjCForwardDecl(Decl)
? GraphObserver::Completeness::Incomplete
: GraphObserver::Completeness::Complete;
AssignUSR(BodyDeclNode, Decl);
Observer.recordRecordNode(BodyDeclNode, GraphObserver::RecordKind::Class,
Completeness, absl::nullopt);
Observer.recordMarkedSource(DeclNode, Marks.GenerateMarkedSource(DeclNode));
Expand Down Expand Up @@ -4883,6 +4898,7 @@ bool IndexerASTVisitor::VisitObjCCategoryDecl(
RangeInCurrentContext(Decl->isImplicit(), DeclNode, NameRange), DeclNode,
absl::nullopt);
AddChildOfEdgeToDeclContext(Decl, DeclNode);
AssignUSR(DeclNode, Decl);
Observer.recordRecordNode(DeclNode, GraphObserver::RecordKind::Category,
GraphObserver::Completeness::Complete,
Marks.GenerateMarkedSource(DeclNode));
Expand Down Expand Up @@ -5173,6 +5189,7 @@ bool IndexerASTVisitor::VisitObjCPropertyDecl(
// TODO(salguarnieri) Think about making a new subkind for properties.
GraphObserver::VariableSubkind::Field,
Marks.GenerateMarkedSource(DeclNode));
AssignUSR(DeclNode, Decl);
if (const auto* TSI = Decl->getTypeSourceInfo()) {
// TODO(zarko): Record storage classes for fields.
AscribeSpelledType(TSI->getTypeLoc(), Decl->getType(), DeclNode);
Expand Down
8 changes: 7 additions & 1 deletion kythe/cxx/indexer/cxx/IndexerASTHooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,6 @@ class IndexerASTVisitor : public clang::RecursiveASTVisitor<IndexerASTVisitor> {
/// enabled.
///
/// USRs are added only for NamedDecls that:
/// * are FunctionDecls
/// * are not under implicit template instantiations
/// * are not in a DeclContext inside a function body
/// * can actually be assigned USRs from Clang
Expand All @@ -696,6 +695,13 @@ class IndexerASTVisitor : public clang::RecursiveASTVisitor<IndexerASTVisitor> {
void AssignUSR(const GraphObserver::NodeId& TargetNode,
const clang::NamedDecl* ND);

/// Assigns a USR to an alias.
void AssignUSR(const GraphObserver::NameId& TargetName,
const GraphObserver::NodeId& AliasedType,
const clang::NamedDecl* ND) {
AssignUSR(Observer.nodeIdForTypeAliasNode(TargetName, AliasedType), ND);
}

GraphObserver::NodeId ApplyBuiltinTypeConstructor(
const char* BuiltinName, const GraphObserver::NodeId& Param);

Expand Down
45 changes: 43 additions & 2 deletions kythe/cxx/indexer/cxx/testdata/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -686,10 +686,51 @@ cc_indexer_test(
)

cc_indexer_test(
name = "usr",
srcs = ["basic/usr.cc"],
name = "usr_alias",
srcs = ["basic/usr_alias.cc"],
check_for_singletons = True,
experimental_usr_byte_size = 20,
ignore_dups = True,
ignore_unimplemented = True,
tags = ["basic"],
)

cc_indexer_test(
name = "usr_enum",
srcs = ["basic/usr_enum.cc"],
check_for_singletons = True,
experimental_usr_byte_size = 20,
ignore_dups = True,
ignore_unimplemented = True,
tags = ["basic"],
)

cc_indexer_test(
name = "usr_function",
srcs = ["basic/usr_function.cc"],
check_for_singletons = True,
experimental_usr_byte_size = 20,
ignore_dups = True,
ignore_unimplemented = True,
tags = ["basic"],
)

cc_indexer_test(
name = "usr_record",
srcs = ["basic/usr_record.cc"],
check_for_singletons = True,
experimental_usr_byte_size = 20,
ignore_dups = True,
ignore_unimplemented = True,
tags = ["basic"],
)

cc_indexer_test(
name = "usr_var",
srcs = ["basic/usr_var.cc"],
check_for_singletons = True,
experimental_usr_byte_size = 20,
ignore_dups = True,
ignore_unimplemented = True,
tags = ["basic"],
)
Expand Down
24 changes: 24 additions & 0 deletions kythe/cxx/indexer/cxx/testdata/basic/usr_alias.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// We index USRs for aliases.

//- @Int defines/binding Int
//- IntUsr /clang/usr Int
//- IntUsr.node/kind clang/usr
using Int = int;

//- @Short defines/binding Short
//- ShortUsr /clang/usr Short
//- ShortUsr.node/kind clang/usr
typedef short Short;

struct S {
//- @Float defines/binding Float
//- FloatUsr /clang/usr Float
//- FloatUsr.node/kind clang/usr
using Float = float;
};

void f() {
//- @Double defines/binding Double
//- !{_ /clang/usr Double}
using Double = double;
}
11 changes: 11 additions & 0 deletions kythe/cxx/indexer/cxx/testdata/basic/usr_enum.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// We index USRs for enums.

//- @E defines/binding E
//- EUsr /clang/usr E
//- EUsr.node/kind clang/usr
enum E {
//- @Etor defines/binding Etor
//- EtorUsr /clang/usr Etor
//- EtorUsr.node/kind clang/usr
Etor
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// We index USRs.
// We index USRs for functions.

//- @foo defines/binding Foo
//- FooUsr /clang/usr Foo
Expand Down
30 changes: 30 additions & 0 deletions kythe/cxx/indexer/cxx/testdata/basic/usr_record.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// We index USRs for records.

//- @C defines/binding C
//- CUsr /clang/usr C
//- CUsr.node/kind clang/usr
class C;

//- @U defines/binding U
//- UUsr /clang/usr U
//- UUsr.node/kind clang/usr
union U;

//- @S defines/binding S
//- SUsr /clang/usr S
//- SUsr.node/kind clang/usr
struct S {
//- @m defines/binding M
//- MUsr /clang/usr M
//- MUsr.node/kind clang/usr
int m;

//- @f defines/binding F
//- FUsr /clang/usr F
//- FUsr.node/kind clang/usr
void f() {
//- @l defines/binding L
//- !{_ /clang/usr L}
int l;
}
};
16 changes: 16 additions & 0 deletions kythe/cxx/indexer/cxx/testdata/basic/usr_var.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// We index USRs for variables.

//- @global defines/binding Global
//- GlobalUSR /clang/usr Global
//- GlobalUSR.node/kind clang/usr
int global;

//- @param defines/binding Param
//- !{_ /clang/usr Param}
void f(int param) { }

void g() {
//- @local defines/binding Local
//- !{_ /clang/usr Local}
int local;
}

0 comments on commit 4d705cf

Please sign in to comment.