Skip to content

Commit

Permalink
Add a test for finding mixed calls (members and non-members)
Browse files Browse the repository at this point in the history
Signed-off-by: Anthony Burzillo <aburzillo@bloomberg.net>
  • Loading branch information
burz authored and ruoso committed Sep 17, 2018
1 parent 6541b32 commit 6044e02
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 64 deletions.
76 changes: 40 additions & 36 deletions src/collectors/find_calls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,47 @@ namespace clangmetatool {

using namespace clang::ast_matchers;

class AnnotateCall1
: public clang::ast_matchers::MatchFinder::MatchCallback {
private:
clang::CompilerInstance *ci;
FindCallsData *data;
public:
AnnotateCall1
(clang::CompilerInstance* ci,
FindCallsData *data)
:ci(ci), data(data) {}

virtual void
run(const clang::ast_matchers::MatchFinder::MatchResult &r)
override {

const clang::CallExpr *c =
r.Nodes.getNodeAs<clang::CallExpr>("call");

const clang::FunctionDecl *f =
r.Nodes.getNodeAs<clang::FunctionDecl>("context");

const clang::DeclRefExpr *e =
r.Nodes.getNodeAs<clang::DeclRefExpr>("ref");

data->call_context.insert
(std::pair
<const clang::FunctionDecl*,
const clang::CallExpr*>(f,c));

data->call_ref.insert
(std::pair
<const clang::CallExpr*,
const clang::DeclRefExpr*>(c,e));

}
namespace {

};
class AnnotateCall1
: public clang::ast_matchers::MatchFinder::MatchCallback {
private:
clang::CompilerInstance *ci;
FindCallsData *data;
public:
AnnotateCall1
(clang::CompilerInstance* ci,
FindCallsData *data)
:ci(ci), data(data) {}

virtual void
run(const clang::ast_matchers::MatchFinder::MatchResult &r)
override {

const clang::CallExpr *c =
r.Nodes.getNodeAs<clang::CallExpr>("call");

const clang::FunctionDecl *f =
r.Nodes.getNodeAs<clang::FunctionDecl>("context");

const clang::DeclRefExpr *e =
r.Nodes.getNodeAs<clang::DeclRefExpr>("ref");

data->call_context.insert
(std::pair
<const clang::FunctionDecl*,
const clang::CallExpr*>(f,c));

data->call_ref.insert
(std::pair
<const clang::CallExpr*,
const clang::DeclRefExpr*>(c,e));

}

};

} // namespace anonymous

class FindCallsImpl {
private:
Expand Down
60 changes: 32 additions & 28 deletions src/collectors/find_cxx_member_calls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,38 @@ namespace clangmetatool {

using namespace clang::ast_matchers;

class AnnotateCall1
: public clang::ast_matchers::MatchFinder::MatchCallback {
private:
clang::CompilerInstance *ci;
FindCXXMemberCallsData *data;
public:
AnnotateCall1
(clang::CompilerInstance* ci,
FindCXXMemberCallsData *data)
:ci(ci), data(data) {}

virtual void
run(const clang::ast_matchers::MatchFinder::MatchResult &r)
override {

const auto c =
r.Nodes.getNodeAs<clang::CXXMemberCallExpr>("call");

const auto f =
r.Nodes.getNodeAs<clang::FunctionDecl>("context");

data->insert
(std::pair
<const clang::FunctionDecl*,
const clang::CXXMemberCallExpr*>(f,c));
}

};
namespace {

class AnnotateCall1
: public clang::ast_matchers::MatchFinder::MatchCallback {
private:
clang::CompilerInstance *ci;
FindCXXMemberCallsData *data;
public:
AnnotateCall1
(clang::CompilerInstance* ci,
FindCXXMemberCallsData *data)
:ci(ci), data(data) {}

virtual void
run(const clang::ast_matchers::MatchFinder::MatchResult &r)
override {

const auto c =
r.Nodes.getNodeAs<clang::CXXMemberCallExpr>("call");

const auto f =
r.Nodes.getNodeAs<clang::FunctionDecl>("context");

data->insert
(std::pair
<const clang::FunctionDecl*,
const clang::CXXMemberCallExpr*>(f,c));
}

};

} // namespace anonymous

class FindCXXMemberCallsImpl {
private:
Expand Down
117 changes: 117 additions & 0 deletions t/025-find-mixed-calls.t.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include "clangmetatool-testconfig.h"

#include <gtest/gtest.h>

#include <clangmetatool/meta_tool_factory.h>
#include <clangmetatool/meta_tool.h>
#include <clangmetatool/collectors/find_calls.h>
#include <clangmetatool/collectors/find_cxx_member_calls.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;

std::string func = std::string("foo");

std::string cNC = std::string("NakedClass");
std::string nNCfoo = std::string("foo");
clangmetatool::collectors::FindCXXMemberCalls fcNCfoo;
std::string nNCbar = std::string("bar");
clangmetatool::collectors::FindCXXMemberCalls fcNCbar;

std::string cBC = std::string("suit::BusinessClass");
std::string nBCbook = std::string("book");
clangmetatool::collectors::FindCXXMemberCalls fcBCbook;
std::string nBCdiatribe = std::string("diatribe");
clangmetatool::collectors::FindCXXMemberCalls fcBCdiatribe;

std::string nHurdur = std::string("hurdur");
clangmetatool::collectors::FindCalls fcHurdur;
public:

MyTool(clang::CompilerInstance* ci, clang::ast_matchers::MatchFinder *f)
: ci(ci)
, fcNCfoo(ci, f, cNC, nNCfoo)
, fcNCbar(ci, f, cNC, nNCbar)
, fcBCbook(ci, f, cBC, nBCbook)
, fcBCdiatribe(ci, f, cBC, nBCdiatribe)
, fcHurdur(ci, f, nHurdur)
{}

void validateMemberFind(clangmetatool::collectors::FindCXXMemberCalls& fc,
const std::string& c, const std::string n) {
const auto data = fc.getData();

ASSERT_EQ(1, data->size());

auto found = data->begin();

EXPECT_EQ(func, found->first->getNameInfo().getAsString());
EXPECT_EQ(c, found->second->getRecordDecl()->getQualifiedNameAsString());
EXPECT_EQ(n, found->second->getMethodDecl()->getNameAsString());
}

void postProcessing
(std::map<std::string, clang::tooling::Replacements> &replacementsMap) {
validateMemberFind(fcNCfoo, cNC, nNCfoo);
validateMemberFind(fcNCbar, cNC, nNCbar);
validateMemberFind(fcBCbook, cBC, nBCbook);
validateMemberFind(fcBCdiatribe, cBC, nBCdiatribe);

auto data = fcHurdur.getData();
ASSERT_EQ(1, data->call_context.size());
const auto& item = *data->call_context.begin();
EXPECT_EQ(func, item.first->getNameAsString());
EXPECT_EQ(nHurdur, item.second->getDirectCallee()->getNameAsString());
}
};

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

int argc = 4;
const char* argv[] = {
"foo",
CMAKE_SOURCE_DIR "/t/data/025-find-mixed-calls/foo.cpp",
"--",
"-xc++"
};

clang::tooling::CommonOptionsParser
optionsParser
( argc, argv,
MyToolCategory );
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 2018 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 ----------------------------------
1 change: 1 addition & 0 deletions t/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ foreach(
022-looping-integer-propagation
023-multi-function-integer-propagation
024-find-cxx-member-calls
025-find-mixed-calls
)

add_executable(${TEST}.t ${TEST}.t.cpp)
Expand Down
29 changes: 29 additions & 0 deletions t/data/025-find-mixed-calls/foo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class NakedClass {
public:
char foo();
char bar(int* yo);
};

char hurdur(int*, char*, unsigned*);

namespace suit {

class BusinessClass {
public:
unsigned long book();
unsigned long long diatribe(char** words) const;
};

} // namespace suit

int foo(NakedClass* nakedC, suit::BusinessClass& businessC) {
nakedC->foo();
businessC.book();

businessC.diatribe(0);
nakedC->bar(0);

hurdur(0, 0, 0);

return 777;
};

0 comments on commit 6044e02

Please sign in to comment.