103 lines
3.5 KiB
C++
103 lines
3.5 KiB
C++
|
//===--- ASTMatchersInternal.cpp - Structural query framework -------------===//
|
||
|
//
|
||
|
// The LLVM Compiler Infrastructure
|
||
|
//
|
||
|
// This file is distributed under the University of Illinois Open Source
|
||
|
// License. See LICENSE.TXT for details.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
//
|
||
|
// Implements the base layer of the matcher framework.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#include "clang/ASTMatchers/ASTMatchers.h"
|
||
|
#include "clang/ASTMatchers/ASTMatchersInternal.h"
|
||
|
|
||
|
namespace clang {
|
||
|
namespace ast_matchers {
|
||
|
namespace internal {
|
||
|
|
||
|
BoundNodesTree::BoundNodesTree() {}
|
||
|
|
||
|
BoundNodesTree::BoundNodesTree(
|
||
|
const std::map<std::string, const Decl*>& DeclBindings,
|
||
|
const std::map<std::string, const Stmt*>& StmtBindings,
|
||
|
const std::vector<BoundNodesTree> RecursiveBindings)
|
||
|
: DeclBindings(DeclBindings), StmtBindings(StmtBindings),
|
||
|
RecursiveBindings(RecursiveBindings) {}
|
||
|
|
||
|
void BoundNodesTree::copyTo(BoundNodesTreeBuilder* Builder) const {
|
||
|
copyBindingsTo(DeclBindings, Builder);
|
||
|
copyBindingsTo(StmtBindings, Builder);
|
||
|
for (std::vector<BoundNodesTree>::const_iterator
|
||
|
I = RecursiveBindings.begin(),
|
||
|
E = RecursiveBindings.end();
|
||
|
I != E; ++I) {
|
||
|
Builder->addMatch(*I);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
void BoundNodesTree::copyBindingsTo(
|
||
|
const T& Bindings, BoundNodesTreeBuilder* Builder) const {
|
||
|
for (typename T::const_iterator I = Bindings.begin(),
|
||
|
E = Bindings.end();
|
||
|
I != E; ++I) {
|
||
|
Builder->setBinding(I->first, I->second);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void BoundNodesTree::visitMatches(Visitor* ResultVisitor) {
|
||
|
std::map<std::string, const Decl*> AggregatedDeclBindings;
|
||
|
std::map<std::string, const Stmt*> AggregatedStmtBindings;
|
||
|
visitMatchesRecursively(ResultVisitor, AggregatedDeclBindings,
|
||
|
AggregatedStmtBindings);
|
||
|
}
|
||
|
|
||
|
void BoundNodesTree::
|
||
|
visitMatchesRecursively(Visitor* ResultVisitor,
|
||
|
std::map<std::string, const Decl*>
|
||
|
AggregatedDeclBindings,
|
||
|
std::map<std::string, const Stmt*>
|
||
|
AggregatedStmtBindings) {
|
||
|
copy(DeclBindings.begin(), DeclBindings.end(),
|
||
|
inserter(AggregatedDeclBindings, AggregatedDeclBindings.begin()));
|
||
|
copy(StmtBindings.begin(), StmtBindings.end(),
|
||
|
inserter(AggregatedStmtBindings, AggregatedStmtBindings.begin()));
|
||
|
if (RecursiveBindings.empty()) {
|
||
|
ResultVisitor->visitMatch(BoundNodes(AggregatedDeclBindings,
|
||
|
AggregatedStmtBindings));
|
||
|
} else {
|
||
|
for (unsigned I = 0; I < RecursiveBindings.size(); ++I) {
|
||
|
RecursiveBindings[I].visitMatchesRecursively(ResultVisitor,
|
||
|
AggregatedDeclBindings,
|
||
|
AggregatedStmtBindings);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BoundNodesTreeBuilder::BoundNodesTreeBuilder() {}
|
||
|
|
||
|
void BoundNodesTreeBuilder::setBinding(const std::string &Id,
|
||
|
const Decl *Node) {
|
||
|
DeclBindings[Id] = Node;
|
||
|
}
|
||
|
|
||
|
void BoundNodesTreeBuilder::setBinding(const std::string &Id,
|
||
|
const Stmt *Node) {
|
||
|
StmtBindings[Id] = Node;
|
||
|
}
|
||
|
|
||
|
void BoundNodesTreeBuilder::addMatch(const BoundNodesTree& Bindings) {
|
||
|
RecursiveBindings.push_back(Bindings);
|
||
|
}
|
||
|
|
||
|
BoundNodesTree BoundNodesTreeBuilder::build() const {
|
||
|
return BoundNodesTree(DeclBindings, StmtBindings, RecursiveBindings);
|
||
|
}
|
||
|
|
||
|
} // end namespace internal
|
||
|
} // end namespace ast_matchers
|
||
|
} // end namespace clang
|