2013-05-16 03:49:05 +08:00
|
|
|
//===--- Registry.cpp - Matcher registry -------------------------===//
|
2013-05-14 17:13:00 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
2013-05-16 03:49:05 +08:00
|
|
|
//===------------------------------------------------------------===//
|
2013-05-14 17:13:00 +08:00
|
|
|
///
|
|
|
|
/// \file
|
|
|
|
/// \brief Registry map populated at static initialization time.
|
|
|
|
///
|
2013-05-16 03:49:05 +08:00
|
|
|
//===------------------------------------------------------------===//
|
2013-05-14 17:13:00 +08:00
|
|
|
|
|
|
|
#include "clang/ASTMatchers/Dynamic/Registry.h"
|
|
|
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
#include "Marshallers.h"
|
|
|
|
#include "clang/ASTMatchers/ASTMatchers.h"
|
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
#include "llvm/Support/ManagedStatic.h"
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace ast_matchers {
|
|
|
|
namespace dynamic {
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using internal::MatcherCreateCallback;
|
|
|
|
|
|
|
|
typedef llvm::StringMap<const MatcherCreateCallback *> ConstructorMap;
|
|
|
|
class RegistryMaps {
|
|
|
|
public:
|
|
|
|
RegistryMaps();
|
|
|
|
~RegistryMaps();
|
|
|
|
|
|
|
|
const ConstructorMap &constructors() const { return Constructors; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
void registerMatcher(StringRef MatcherName, MatcherCreateCallback *Callback);
|
|
|
|
ConstructorMap Constructors;
|
|
|
|
};
|
|
|
|
|
|
|
|
void RegistryMaps::registerMatcher(StringRef MatcherName,
|
|
|
|
MatcherCreateCallback *Callback) {
|
|
|
|
Constructors[MatcherName] = Callback;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define REGISTER_MATCHER(name) \
|
|
|
|
registerMatcher(#name, internal::makeMatcherAutoMarshall( \
|
|
|
|
::clang::ast_matchers::name, #name));
|
|
|
|
|
|
|
|
/// \brief Generate a registry map with all the known matchers.
|
|
|
|
RegistryMaps::RegistryMaps() {
|
|
|
|
// TODO: This list is not complete. It only has non-overloaded matchers,
|
|
|
|
// which are the simplest to add to the system. Overloaded matchers require
|
|
|
|
// more supporting code that was omitted from the first revision for
|
|
|
|
// simplicitly of code review.
|
|
|
|
|
|
|
|
REGISTER_MATCHER(binaryOperator);
|
|
|
|
REGISTER_MATCHER(bindTemporaryExpr);
|
|
|
|
REGISTER_MATCHER(boolLiteral);
|
|
|
|
REGISTER_MATCHER(callExpr);
|
|
|
|
REGISTER_MATCHER(characterLiteral);
|
|
|
|
REGISTER_MATCHER(compoundStmt);
|
|
|
|
REGISTER_MATCHER(conditionalOperator);
|
|
|
|
REGISTER_MATCHER(constCastExpr);
|
|
|
|
REGISTER_MATCHER(constructExpr);
|
|
|
|
REGISTER_MATCHER(constructorDecl);
|
|
|
|
REGISTER_MATCHER(declRefExpr);
|
|
|
|
REGISTER_MATCHER(declStmt);
|
|
|
|
REGISTER_MATCHER(defaultArgExpr);
|
|
|
|
REGISTER_MATCHER(doStmt);
|
|
|
|
REGISTER_MATCHER(dynamicCastExpr);
|
|
|
|
REGISTER_MATCHER(explicitCastExpr);
|
|
|
|
REGISTER_MATCHER(expr);
|
|
|
|
REGISTER_MATCHER(fieldDecl);
|
|
|
|
REGISTER_MATCHER(forStmt);
|
|
|
|
REGISTER_MATCHER(functionDecl);
|
|
|
|
REGISTER_MATCHER(hasAnyParameter);
|
|
|
|
REGISTER_MATCHER(hasAnySubstatement);
|
|
|
|
REGISTER_MATCHER(hasConditionVariableStatement);
|
|
|
|
REGISTER_MATCHER(hasDestinationType);
|
|
|
|
REGISTER_MATCHER(hasEitherOperand);
|
|
|
|
REGISTER_MATCHER(hasFalseExpression);
|
|
|
|
REGISTER_MATCHER(hasImplicitDestinationType);
|
|
|
|
REGISTER_MATCHER(hasInitializer);
|
|
|
|
REGISTER_MATCHER(hasLHS);
|
|
|
|
REGISTER_MATCHER(hasName);
|
|
|
|
REGISTER_MATCHER(hasObjectExpression);
|
|
|
|
REGISTER_MATCHER(hasRHS);
|
|
|
|
REGISTER_MATCHER(hasSourceExpression);
|
|
|
|
REGISTER_MATCHER(hasTrueExpression);
|
|
|
|
REGISTER_MATCHER(hasUnaryOperand);
|
|
|
|
REGISTER_MATCHER(ifStmt);
|
|
|
|
REGISTER_MATCHER(implicitCastExpr);
|
|
|
|
REGISTER_MATCHER(integerLiteral);
|
|
|
|
REGISTER_MATCHER(isArrow);
|
|
|
|
REGISTER_MATCHER(isConstQualified);
|
|
|
|
REGISTER_MATCHER(isImplicit);
|
|
|
|
REGISTER_MATCHER(member);
|
|
|
|
REGISTER_MATCHER(memberExpr);
|
|
|
|
REGISTER_MATCHER(methodDecl);
|
|
|
|
REGISTER_MATCHER(namedDecl);
|
|
|
|
REGISTER_MATCHER(newExpr);
|
|
|
|
REGISTER_MATCHER(ofClass);
|
|
|
|
REGISTER_MATCHER(on);
|
|
|
|
REGISTER_MATCHER(onImplicitObjectArgument);
|
|
|
|
REGISTER_MATCHER(operatorCallExpr);
|
|
|
|
REGISTER_MATCHER(recordDecl);
|
|
|
|
REGISTER_MATCHER(reinterpretCastExpr);
|
|
|
|
REGISTER_MATCHER(staticCastExpr);
|
|
|
|
REGISTER_MATCHER(stmt);
|
|
|
|
REGISTER_MATCHER(stringLiteral);
|
|
|
|
REGISTER_MATCHER(switchCase);
|
|
|
|
REGISTER_MATCHER(to);
|
|
|
|
REGISTER_MATCHER(unaryOperator);
|
|
|
|
REGISTER_MATCHER(varDecl);
|
|
|
|
REGISTER_MATCHER(whileStmt);
|
|
|
|
}
|
|
|
|
|
|
|
|
RegistryMaps::~RegistryMaps() {
|
|
|
|
for (ConstructorMap::iterator it = Constructors.begin(),
|
|
|
|
end = Constructors.end();
|
|
|
|
it != end; ++it) {
|
|
|
|
delete it->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static llvm::ManagedStatic<RegistryMaps> RegistryData;
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
// static
|
|
|
|
DynTypedMatcher *Registry::constructMatcher(StringRef MatcherName,
|
|
|
|
const SourceRange &NameRange,
|
|
|
|
ArrayRef<ParserValue> Args,
|
|
|
|
Diagnostics *Error) {
|
|
|
|
ConstructorMap::const_iterator it =
|
|
|
|
RegistryData->constructors().find(MatcherName);
|
|
|
|
if (it == RegistryData->constructors().end()) {
|
|
|
|
Error->pushErrorFrame(NameRange, Error->ET_RegistryNotFound)
|
|
|
|
<< MatcherName;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return it->second->run(NameRange, Args, Error);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace dynamic
|
|
|
|
} // namespace ast_matchers
|
|
|
|
} // namespace clang
|