From ed017452ee96cede7928ee2c96e8e918e7014eb8 Mon Sep 17 00:00:00 2001 From: Kojo Adams Date: Thu, 1 Jun 2023 09:55:08 -0400 Subject: [PATCH] Correctly find the location when a macro is called within a macro Assuming we have the following code ```cpp int main() { call_print_foo(); } ``` The current code doesn't note that reference to print_foo() since it happens in `scratch space`. This PR adds support for it. Signed-off-by: Kojo Adams --- .../include_graph/include_graph_util.cpp | 25 ++++++++++--------- .../044-type-access-through-expansion/foo.cpp | 4 ++- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/collectors/include_graph/include_graph_util.cpp b/src/collectors/include_graph/include_graph_util.cpp index 41d1e82..937871c 100644 --- a/src/collectors/include_graph/include_graph_util.cpp +++ b/src/collectors/include_graph/include_graph_util.cpp @@ -170,6 +170,17 @@ static void add_usage(clang::CompilerInstance *ci, IncludeGraphData *data, data->usage_reference_count[edge]++; } +// Gets a sensible clang::SourceLocation even in the presence of a macro. +clang::SourceLocation get_canonical_location(clang::SourceManager &sm, + clang::SourceLocation loc) { + clang::SourceLocation spellingLoc = sm.getSpellingLoc(loc); + // this usually happens when there is token pasting + if (sm.isWrittenInScratchSpace(spellingLoc)) { + loc = sm.getExpansionRange(loc).getBegin(); + } + return loc; +} + void add_macro_reference(clang::CompilerInstance *ci, IncludeGraphData *data, clangmetatool::types::MacroReferenceInfo m) { if (!std::get<1>(m)) @@ -179,7 +190,8 @@ void add_macro_reference(clang::CompilerInstance *ci, IncludeGraphData *data, if (!info) return; - clang::SourceLocation usageLoc = std::get<0>(m).getLocation(); + clang::SourceLocation usageLoc = get_canonical_location( + ci->getSourceManager(), std::get<0>(m).getLocation()); clang::SourceLocation defLoc = info->getDefinitionLoc(); add_usage(ci, data, usageLoc, defLoc, m, data->macro_references); @@ -196,17 +208,6 @@ void add_redeclaration(clang::CompilerInstance *ci, IncludeGraphData *data, data->redeclarations); } -// Gets a sensible clang::SourceLocation even in the presence of a macro. -clang::SourceLocation get_canonical_location(clang::SourceManager &sm, - clang::SourceLocation loc) { - clang::SourceLocation spellingLoc = sm.getSpellingLoc(loc); - // this usually happens when there is token pasting - if (sm.isWrittenInScratchSpace(spellingLoc)) { - loc = sm.getExpansionRange(loc).getBegin(); - } - return loc; -} - void add_decl_reference(clang::CompilerInstance *ci, IncludeGraphData *data, const clang::DeclRefExpr *e) { diff --git a/t/data/044-type-access-through-expansion/foo.cpp b/t/data/044-type-access-through-expansion/foo.cpp index a2c81b7..0768cb6 100644 --- a/t/data/044-type-access-through-expansion/foo.cpp +++ b/t/data/044-type-access-through-expansion/foo.cpp @@ -1,8 +1,10 @@ #include "foo.h" #include "macro.h" +#define CALL_FOO2(v) FOO2(v) + void function() { FOO1() f1; FOO2(v); - FOO1() f3; + CALL_FOO2(f3); }