Skip to content

Commit

Permalink
Merge pull request #75 from samanpa/optional_type
Browse files Browse the repository at this point in the history
Locate declRefs that are used in a macro correctly
  • Loading branch information
samanpa authored May 2, 2023
2 parents 6c24de8 + f73a718 commit 2eb1d0c
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/collectors/include_graph/include_graph_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,9 @@ void add_decl_reference(clang::CompilerInstance *ci, IncludeGraphData *data,
if (!d)
return;
clang::SourceLocation locDef = d->getLocation();
clang::SourceLocation expansionLoc = ci->getSourceManager().getExpansionLoc(locUse);

add_usage(ci, data, locUse, locDef, e, data->decl_references);
add_usage(ci, data, expansionLoc, locDef, e, data->decl_references);
}

template <typename T>
Expand Down Expand Up @@ -257,8 +258,8 @@ void add_type_reference(clang::CompilerInstance *ci, IncludeGraphData *data,
return;
}

add_usage(ci, data, n->getBeginLoc(), decl->getLocation(), n,
data->type_references);
add_usage(ci, data, ci->getSourceManager().getExpansionLoc(n->getBeginLoc()),
decl->getLocation(), n, data->type_references);
}
} // namespace include_graph
} // namespace collectors
Expand Down
100 changes: 100 additions & 0 deletions t/043-variable-access-through-expansion.t.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "clangmetatool-testconfig.h"

#include <gtest/gtest.h>

#include <clangmetatool/meta_tool_factory.h>
#include <clangmetatool/meta_tool.h>
#include <clangmetatool/collectors/include_graph.h>

#include <clang/Frontend/FrontendAction.h>
#include <clang/Tooling/Core/Replacement.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
#include <clang/Tooling/Refactoring.h>
#include <llvm/Support/CommandLine.h>

class MyTool {
private:
clang::CompilerInstance* ci;
clangmetatool::collectors::IncludeGraph graph;
public:
MyTool(clang::CompilerInstance* ci, clang::ast_matchers::MatchFinder *f)
:ci(ci), graph(ci, f) {
}
void postProcessing
(std::map<std::string, clang::tooling::Replacements> &replacementsMap) {
clangmetatool::collectors::IncludeGraphData *data = graph.getData();

// file ID 0 to 1, aka foo.cpp to paste.h
auto edge = std::make_pair(0, 1);
ASSERT_EQ(data->usage_reference_count.count(edge), 1);
ASSERT_EQ(data->usage_reference_count[edge], 2); // reference PASTE 2x

// file ID from 0 to 2, aka foo.cpp to global.h
edge = std::make_pair(0, 2);
ASSERT_EQ(data->usage_reference_count.count(edge), 1);
// GLOBAL1 .. GLOBAL4 are referenced
ASSERT_EQ(data->usage_reference_count[edge], 4);

// file ID from 2 to 1, aka paste.h to global.h
edge = std::make_pair(1, 2);
ASSERT_EQ(data->usage_reference_count.count(edge), 1);
ASSERT_EQ(data->usage_reference_count[edge], 0);

// file ID from 0 to 3, aka foo.cpp to macro.h
edge = std::make_pair(0, 3);
ASSERT_EQ(data->usage_reference_count[edge], 2); // USE 2 macros from here

// file ID from 3 to 2, aka macro.h to global.h
edge = std::make_pair(3, 2);
// Even though macro.h has a "spelling" of GLOBAL3 in macro.h it does
// not include global.h and does not directly reference GLOBAL3
// only callers of the macro actually reference global.h
ASSERT_EQ(data->usage_reference_count.count(edge), 1);
ASSERT_EQ(data->usage_reference_count[edge], 0);
}
};

TEST(use_meta_tool, factory) {
llvm::cl::OptionCategory MyToolCategory("my-tool options");

const char* argv[] = {
"foo",
CMAKE_SOURCE_DIR "/t/data/043-variable-access-through-expansion/foo.cpp",
"--",
"-xc++"
};
int argc = sizeof(argv) / sizeof(argv[0]);

auto result = clang::tooling::CommonOptionsParser::create(
argc, argv, MyToolCategory, llvm::cl::OneOrMore);
ASSERT_TRUE(!!result);
clang::tooling::CommonOptionsParser& optionsParser = result.get();

clang::tooling::RefactoringTool tool
( optionsParser.getCompilations(),
optionsParser.getSourcePathList());

clangmetatool::MetaToolFactory< clangmetatool::MetaTool<MyTool> >
raf(tool.getReplacements());

int r = tool.runAndSave(&raf);
ASSERT_EQ(0, r);
}


// ----------------------------------------------------------------------------
// Copyright 2023 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
83 changes: 83 additions & 0 deletions t/044-type-access-through-expansion.t.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "clangmetatool-testconfig.h"

#include <gtest/gtest.h>

#include <clangmetatool/meta_tool_factory.h>
#include <clangmetatool/meta_tool.h>
#include <clangmetatool/collectors/include_graph.h>

#include <clang/Frontend/FrontendAction.h>
#include <clang/Tooling/Core/Replacement.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
#include <clang/Tooling/Refactoring.h>
#include <llvm/Support/CommandLine.h>

class MyTool {
private:
clang::CompilerInstance* ci;
clangmetatool::collectors::IncludeGraph graph;
public:
MyTool(clang::CompilerInstance* ci, clang::ast_matchers::MatchFinder *f)
:ci(ci), graph(ci, f) {
}
void postProcessing
(std::map<std::string, clang::tooling::Replacements> &replacementsMap) {
clangmetatool::collectors::IncludeGraphData *data = graph.getData();

// file ID 0 to 1, aka foo.cpp to foo.h
auto edge = std::make_pair(0, 1);
ASSERT_EQ(data->usage_reference_count.count(edge), 1);
ASSERT_EQ(data->usage_reference_count[edge], 1);

// file ID from 0 to 2, aka foo.cpp to macro.h
edge = std::make_pair(0, 2);
ASSERT_EQ(data->usage_reference_count.count(edge), 1);
// We reference the macros in macro.h 3 times.
ASSERT_EQ(data->usage_reference_count[edge], 3);
}
};

TEST(use_meta_tool, factory) {
llvm::cl::OptionCategory MyToolCategory("my-tool options");

const char* argv[] = {
"foo",
CMAKE_SOURCE_DIR "/t/data/044-type-access-through-expansion/foo.cpp",
"--",
"-xc++"
};
int argc = sizeof(argv) / sizeof(argv[0]);

auto result = clang::tooling::CommonOptionsParser::create(
argc, argv, MyToolCategory, llvm::cl::OneOrMore);
ASSERT_TRUE(!!result);
clang::tooling::CommonOptionsParser& optionsParser = result.get();

clang::tooling::RefactoringTool tool
( optionsParser.getCompilations(),
optionsParser.getSourcePathList());

clangmetatool::MetaToolFactory< clangmetatool::MetaTool<MyTool> >
raf(tool.getReplacements());

int r = tool.runAndSave(&raf);
ASSERT_EQ(0, r);
}


// ----------------------------------------------------------------------------
// Copyright 2023 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
2 changes: 2 additions & 0 deletions t/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ foreach(
040-includegraph-nested-using
041-expand-range-if-valid
042-generic-using-include-graph
043-variable-access-through-expansion
044-type-access-through-expansion
)

add_executable(${TEST}.t ${TEST}.t.cpp)
Expand Down
Empty file.
13 changes: 13 additions & 0 deletions t/data/043-variable-access-through-expansion/foo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "paste.h"
#include "macro.h"
#include "global.h"

int bar()
{
return PASTE(GLO, BAL1) + PASTE(GL, OBAL2);
}

int baz()
{
return ANOTHER_PASTE(GL, OBAL4) + REFERENCE_GLOBAL3();
}
9 changes: 9 additions & 0 deletions t/data/043-variable-access-through-expansion/global.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef GLOBAL_H
#define GLOBAL_H

int GLOBAL1;
int GLOBAL2;
int GLOBAL3;
int GLOBAL4;

#endif
5 changes: 5 additions & 0 deletions t/data/043-variable-access-through-expansion/macro.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "global.h"

#define ANOTHER_PASTE(x, y) x##y

#define REFERENCE_GLOBAL3() GLOBAL3
3 changes: 3 additions & 0 deletions t/data/043-variable-access-through-expansion/paste.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "global.h"

#define PASTE(x, y ) x ## y
8 changes: 8 additions & 0 deletions t/data/044-type-access-through-expansion/foo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "foo.h"
#include "macro.h"

void function() {
FOO1() f1;
FOO2(v);
FOO1() f3;
}
6 changes: 6 additions & 0 deletions t/data/044-type-access-through-expansion/foo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef FOO_H
#define FOO_H

class Foo {};

#endif
9 changes: 9 additions & 0 deletions t/data/044-type-access-through-expansion/macro.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef MACRO_H
#define MACRO_H

#define FOO1() Foo

#define FOO2(v) Foo v;


#endif

0 comments on commit 2eb1d0c

Please sign in to comment.