Skip to content

Commit

Permalink
Add collector for references (#13)
Browse files Browse the repository at this point in the history
Signed-off-by: Ajmal Sharif <asharif10@bloomberg.net>
  • Loading branch information
HaltCatchFire authored and ruoso committed Aug 8, 2018
1 parent 04da5ce commit cfc9313
Show file tree
Hide file tree
Showing 9 changed files with 769 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ add_library(
src/find_calls/find_calls.cpp

src/definitions/definitions.cpp

src/references/references.cpp
)
target_include_directories(
clangmetatool
Expand Down
64 changes: 64 additions & 0 deletions include/clangmetatool/collectors/references.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#ifndef INCLUDED_CLANGMETATOOL_COLLECTORS_REFERENCES_H
#define INCLUDED_CLANGMETATOOL_COLLECTORS_REFERENCES_H

#include <clang/Frontend/CompilerInstance.h>
#include <clang/ASTMatchers/ASTMatchFinder.h>

#include <clangmetatool/collectors/references_data.h>

namespace clangmetatool {
namespace collectors {

/**
* Forward declaration to implementation details of the collector.
*/
class ReferencesImpl;

/**
* References data collector. Collects References of functions and variables with global storage.
*/
class References {
private:
/**
* Pointer to implementation.
*/
ReferencesImpl* impl;
public:
/**
* Explicit constructor to allow for implementation details.
* - ci is a pointer to an instance of the clang compiler
* - f is a pointer to an instance of the MatchFinder class
*/
References(clang::CompilerInstance *ci, clang::ast_matchers::MatchFinder *f);

/**
* Explicit destructor.
*/
~References();

/**
* Get the pointer to the object containing the data; populated or not.
*/
ReferencesData* getData();
};

} // namespace collectors
} // namespace clangmetatool

#endif //INCLUDED_CLANGMETATOOL_COLLECTORS_REFERENCES_H

// ----------------------------------------------------------------------------
// 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 ----------------------------------
53 changes: 53 additions & 0 deletions include/clangmetatool/collectors/references_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#ifndef INCLUDED_CLANGMETATOOL_COLLECTORS_REFERENCES_DATA_H
#define INCLUDED_CLANGMETATOOL_COLLECTORS_REFERENCES_DATA_H

#include <unordered_map>

#include <clang/AST/Decl.h>

#include <clangmetatool/types/file_uid.h>

namespace clangmetatool {
namespace collectors {

/**
* The data collected by the References collector.
*/
class ReferencesData {
public:
/**
* Contains all definitions that reference other identifiers.
* Key is the definition of a class/function/variable.
* Value is the declaration of an identifier referenced by that class/function/variable.
*/
std::unordered_multimap<const clang::NamedDecl *, const clang::NamedDecl *> deps;

/**
* Contains all references that are used in definitions.
* (This is the inverse of "deps".)
* Key is the declaration of the identifier referenced by a class/function/variable.
* Value is the definition of a class/function/variable that references the Key.
*/
std::unordered_multimap<const clang::NamedDecl *, const clang::NamedDecl *> refs;
};

} // namespace collectors
} // namespace clangmetatool

#endif //INCLUDED_CLANGMETATOOL_COLLECTORS_REFERENCES_DATA_H

// ----------------------------------------------------------------------------
// 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 ----------------------------------
184 changes: 184 additions & 0 deletions src/references/references.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#include <clang/Basic/SourceManager.h>

#include <clangmetatool/collectors/references.h>

#include <utility>

namespace clangmetatool {
namespace collectors {

namespace {

using namespace clang::ast_matchers;

class ReferencesDataAppender : public MatchFinder::MatchCallback {
private:
clang::CompilerInstance *ci;
ReferencesData *data;
public:
ReferencesDataAppender(clang::CompilerInstance *ci, ReferencesData *data)
: ci(ci), data(data) {}
virtual void run(const MatchFinder::MatchResult & r) override {
const clang::NamedDecl *ref = r.Nodes.getNodeAs<clang::NamedDecl>("reference");
if (ref == nullptr) return;

const clang::NamedDecl *ctxt = r.Nodes.getNodeAs<clang::NamedDecl>("context");
if (ctxt == nullptr) return;

data->refs.insert(std::make_pair(ref, ctxt));
data->deps.insert(std::make_pair(ctxt, ref));
}
};

} // close anonymous namespace

class ReferencesImpl {
private:
ReferencesData data;

StatementMatcher funcContextMatcher =
anyOf(
// matches vars and funcs
declRefExpr(
allOf(
hasAncestor(
functionDecl(
isDefinition()
).bind("context")
),
hasDeclaration(
anyOf(
varDecl(
allOf(
unless(
parmVarDecl()
),
hasGlobalStorage()
)
).bind("reference"),
functionDecl().bind("reference")
)
)
)
),
// matches C++ classes from constructor
cxxConstructExpr(
allOf(
hasAncestor(
functionDecl(
isDefinition()
).bind("context")
),
hasDeclaration(
namedDecl().bind("reference")
)
)
)
);

StatementMatcher varContextMatcher =
anyOf(
// matches vars and funcs
declRefExpr(
allOf(
hasAncestor(
varDecl(
allOf(
isDefinition(), hasGlobalStorage()
)
).bind("context")
),
hasDeclaration(
anyOf(
varDecl().bind("reference"),
functionDecl().bind("reference")
)
)
)
),
// matches C++ classes from constructor
cxxConstructExpr(
allOf(
hasAncestor(
varDecl(
allOf(
isDefinition(), hasGlobalStorage()
)
).bind("context")
),
hasDeclaration(
namedDecl().bind("reference")
)
)
)
);

DeclarationMatcher funcInRecordMatcher =
recordDecl(
allOf(
isDefinition(),
hasDescendant(
functionDecl().bind("reference")
)

)
).bind("context");

DeclarationMatcher fieldInRecordMatcher =
recordDecl(
allOf(
isDefinition(),
hasDescendant(
fieldDecl().bind("reference")
)
)
).bind("context");

ReferencesDataAppender refAppender;

public:
ReferencesImpl (clang::CompilerInstance *ci
, MatchFinder *f)
: refAppender(ci, &data)
{
f->addMatcher(funcContextMatcher, &refAppender);
f->addMatcher(varContextMatcher, &refAppender);
f->addMatcher(funcInRecordMatcher, &refAppender);
f->addMatcher(fieldInRecordMatcher, &refAppender);
}

ReferencesData* getData() {
return &data;
}
};

References::References(clang::CompilerInstance *ci, MatchFinder *f) {
impl = new ReferencesImpl(ci, f);
}

References::~References() {
delete impl;
}

ReferencesData* References::getData() {
return impl->getData();
}

} // namespace collectors
} // namespace clangmetatool

// ----------------------------------------------------------------------------
// 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 ----------------------------------
Loading

0 comments on commit cfc9313

Please sign in to comment.