summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2011-06-02 16:58:33 +0000
committerManuel Klimek <klimek@google.com>2011-06-02 16:58:33 +0000
commit16f213142f8f8f5410672205a19f79ed3c232929 (patch)
treea11e620036d64fa4f97884a4ea22c26c06ee3b24
parentfb3f4aad0436a9c40e9130598162150890c405b5 (diff)
Reverts the Tooling changes as requested by Chris.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132462 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--examples/CMakeLists.txt1
-rw-r--r--examples/Makefile2
-rw-r--r--examples/Tooling/CMakeLists.txt7
-rw-r--r--examples/Tooling/ClangCheck.cpp47
-rw-r--r--examples/Tooling/Makefile26
-rw-r--r--examples/Tooling/RemoveCStrCalls/CMakeLists.txt5
-rw-r--r--examples/Tooling/RemoveCStrCalls/Makefile23
-rw-r--r--examples/Tooling/RemoveCStrCalls/RemoveCStrCalls.cpp229
-rwxr-xr-xexamples/Tooling/replace.py50
-rw-r--r--include/clang/Tooling/ASTMatchers.h1735
-rw-r--r--include/clang/Tooling/Tooling.h142
-rw-r--r--include/clang/Tooling/VariadicFunction.h1398
-rw-r--r--lib/CMakeLists.txt1
-rwxr-xr-xlib/Makefile2
-rw-r--r--lib/Tooling/ASTMatchers.cpp564
-rw-r--r--lib/Tooling/CMakeLists.txt7
-rw-r--r--lib/Tooling/JsonCompileCommandLineDatabase.cpp214
-rw-r--r--lib/Tooling/JsonCompileCommandLineDatabase.h107
-rw-r--r--lib/Tooling/Makefile15
-rw-r--r--lib/Tooling/Tooling.cpp403
-rw-r--r--test/Tooling/remove-cstr-calls.cpp21
-rw-r--r--unittests/CMakeLists.txt15
-rw-r--r--unittests/Tooling/ASTMatchersTest.cpp1604
-rw-r--r--unittests/Tooling/JsonCompileCommandLineDatabaseTest.cpp246
-rw-r--r--unittests/Tooling/ToolingTest.cpp175
25 files changed, 2 insertions, 7037 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 8e16ef1c6c..317bc81637 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,3 +1,2 @@
add_subdirectory(clang-interpreter)
add_subdirectory(PrintFunctionNames)
-add_subdirectory(Tooling)
diff --git a/examples/Makefile b/examples/Makefile
index 9f1615c2f0..8cb431d739 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -9,6 +9,6 @@
CLANG_LEVEL := ..
-PARALLEL_DIRS := clang-interpreter PrintFunctionNames Tooling
+PARALLEL_DIRS := clang-interpreter PrintFunctionNames
include $(CLANG_LEVEL)/Makefile
diff --git a/examples/Tooling/CMakeLists.txt b/examples/Tooling/CMakeLists.txt
deleted file mode 100644
index 01132b858a..0000000000
--- a/examples/Tooling/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-set(LLVM_USED_LIBS clangTooling clangBasic)
-
-add_clang_executable(clang-check
- ClangCheck.cpp
- )
-
-add_subdirectory(RemoveCStrCalls)
diff --git a/examples/Tooling/ClangCheck.cpp b/examples/Tooling/ClangCheck.cpp
deleted file mode 100644
index ad88e023ca..0000000000
--- a/examples/Tooling/ClangCheck.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//===- examples/Tooling/ClangCheck.cpp - Clang check tool -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a clang-check tool that runs the
-// clang::SyntaxOnlyAction over a number of translation units.
-//
-// Usage:
-// clang-check <cmake-output-dir> <file1> <file2> ...
-//
-// Where <cmake-output-dir> is a CMake build directory in which a file named
-// compile_commands.json exists (enable -DCMAKE_EXPORT_COMPILE_COMMANDS in
-// CMake to get this output).
-//
-// <file1> ... specify the paths of files in the CMake source tree. This path
-// is looked up in the compile command database. If the path of a file is
-// absolute, it needs to point into CMake's source tree. If the path is
-// relative, the current working directory needs to be in the CMake source
-// tree and the file must be in a subdirectory of the current working
-// directory. "./" prefixes in the relative files will be automatically
-// removed, but the rest of a relative path must be a suffix of a path in
-// the compile command line database.
-//
-// For example, to use clang-check on all files in a subtree of the source
-// tree, use:
-//
-// /path/in/subtree $ find . -name '*.cpp'| xargs clang-check /path/to/source
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Frontend/FrontendActions.h"
-#include "clang/Tooling/Tooling.h"
-
-class SyntaxOnlyActionFactory : public clang::tooling::FrontendActionFactory {
- public:
- virtual clang::FrontendAction *New() { return new clang::SyntaxOnlyAction; }
-};
-
-int main(int argc, char **argv) {
- clang::tooling::ClangTool Tool(argc, argv);
- return Tool.Run(new SyntaxOnlyActionFactory);
-}
diff --git a/examples/Tooling/Makefile b/examples/Tooling/Makefile
deleted file mode 100644
index 4daa9c7f83..0000000000
--- a/examples/Tooling/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-##===- examples/Tooling/Makefile ---------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-CLANG_LEVEL := ../..
-
-TOOLNAME = clang-check
-NO_INSTALL = 1
-
-# No plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
-
-LINK_COMPONENTS := support mc
-USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a \
- clangTooling.a clangParse.a clangSema.a clangAnalysis.a \
- clangAST.a clangLex.a clangBasic.a
-
-PARALLEL_DIRS := RemoveCStrCalls
-
-include $(CLANG_LEVEL)/Makefile
-
diff --git a/examples/Tooling/RemoveCStrCalls/CMakeLists.txt b/examples/Tooling/RemoveCStrCalls/CMakeLists.txt
deleted file mode 100644
index 66debc9288..0000000000
--- a/examples/Tooling/RemoveCStrCalls/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-set(LLVM_USED_LIBS clangTooling clangBasic clangAST)
-
-add_clang_executable(remove-cstr-calls
- RemoveCStrCalls.cpp
- )
diff --git a/examples/Tooling/RemoveCStrCalls/Makefile b/examples/Tooling/RemoveCStrCalls/Makefile
deleted file mode 100644
index 44de60ebe9..0000000000
--- a/examples/Tooling/RemoveCStrCalls/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- examples/Tooling/RemoveCStrCalls/Makefile -----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-CLANG_LEVEL := ../../..
-
-TOOLNAME = remove-cstr-calls
-NO_INSTALL = 1
-
-# No plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
-
-LINK_COMPONENTS := support mc
-USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
- clangParse.a clangSema.a clangAnalysis.a \
- clangAST.a clangLex.a clangBasic.a
-
-include $(CLANG_LEVEL)/Makefile
diff --git a/examples/Tooling/RemoveCStrCalls/RemoveCStrCalls.cpp b/examples/Tooling/RemoveCStrCalls/RemoveCStrCalls.cpp
deleted file mode 100644
index 6de9dd986a..0000000000
--- a/examples/Tooling/RemoveCStrCalls/RemoveCStrCalls.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-//===- examples/Tooling/RemoveCStrCalls.cpp - Redundant c_str call removal ===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a tool that prints replacements that remove redundant
-// calls of c_str() on strings.
-//
-// Usage:
-// remove-cstr-calls <cmake-output-dir> <file1> <file2> ...
-//
-// Where <cmake-output-dir> is a CMake build directory in which a file named
-// compile_commands.json exists (enable -DCMAKE_EXPORT_COMPILE_COMMANDS in
-// CMake to get this output).
-//
-// <file1> ... specify the paths of files in the CMake source tree. This path
-// is looked up in the compile command database. If the path of a file is
-// absolute, it needs to point into CMake's source tree. If the path is
-// relative, the current working directory needs to be in the CMake source
-// tree and the file must be in a subdirectory of the current working
-// directory. "./" prefixes in the relative files will be automatically
-// removed, but the rest of a relative path must be a suffix of a path in
-// the compile command line database.
-//
-// For example, to use remove-cstr-calls on all files in a subtree of the
-// source tree, use:
-//
-// /path/in/subtree $ find . -name '*.cpp'|
-// xargs remove-cstr-calls /path/to/source
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/SourceManager.h"
-#include "clang/Frontend/FrontendActions.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Tooling/ASTMatchers.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
-
-using namespace clang::tooling::match;
-
-// FIXME: Pull out helper methods in here into more fitting places.
-
-// Returns the text that makes up 'node' in the source.
-// Returns an empty string if the text cannot be found.
-template <typename T>
-std::string GetText(const clang::SourceManager &SourceManager, const T &Node) {
- clang::SourceLocation StartSpellingLocatino =
- SourceManager.getSpellingLoc(Node.getLocStart());
- clang::SourceLocation EndSpellingLocation =
- SourceManager.getSpellingLoc(Node.getLocEnd());
- if (!StartSpellingLocatino.isValid() || !EndSpellingLocation.isValid()) {
- return std::string();
- }
- bool Invalid = true;
- const char *Text =
- SourceManager.getCharacterData(StartSpellingLocatino, &Invalid);
- if (Invalid) {
- return std::string();
- }
- std::pair<clang::FileID, unsigned> Start =
- SourceManager.getDecomposedLoc(StartSpellingLocatino);
- std::pair<clang::FileID, unsigned> End =
- SourceManager.getDecomposedLoc(clang::Lexer::getLocForEndOfToken(
- EndSpellingLocation, 0, SourceManager, clang::LangOptions()));
- if (Start.first != End.first) {
- // Start and end are in different files.
- return std::string();
- }
- if (End.second < Start.second) {
- // Shuffling text with macros may cause this.
- return std::string();
- }
- return std::string(Text, End.second - Start.second);
-}
-
-// Returns the position of the spelling location of a node inside a file.
-// The format is:
-// "<start_line>:<start_column>:<end_line>:<end_column>"
-template <typename T1>
-void PrintPosition(
- llvm::raw_ostream &OS,
- const clang::SourceManager &SourceManager, const T1 &Node) {
- clang::SourceLocation StartSpellingLocation =
- SourceManager.getSpellingLoc(Node.getLocStart());
- clang::SourceLocation EndSpellingLocation =
- SourceManager.getSpellingLoc(Node.getLocEnd());
- clang::PresumedLoc Start =
- SourceManager.getPresumedLoc(StartSpellingLocation);
- clang::SourceLocation EndToken = clang::Lexer::getLocForEndOfToken(
- EndSpellingLocation, 1, SourceManager, clang::LangOptions());
- clang::PresumedLoc End = SourceManager.getPresumedLoc(EndToken);
- OS << Start.getLine() << ":" << Start.getColumn() << ":"
- << End.getLine() << ":" << End.getColumn();
-}
-
-class ReportPosition : public clang::tooling::MatchFinder::MatchCallback {
- public:
- virtual void Run(const clang::tooling::MatchFinder::MatchResult &Result) {
- llvm::outs() << "Found!\n";
- }
-};
-
-// Return true if expr needs to be put in parens when it is an
-// argument of a prefix unary operator, e.g. when it is a binary or
-// ternary operator syntactically.
-bool NeedParensAfterUnaryOperator(const clang::Expr &ExprNode) {
- if (llvm::dyn_cast<clang::BinaryOperator>(&ExprNode) ||
- llvm::dyn_cast<clang::ConditionalOperator>(&ExprNode)) {
- return true;
- }
- if (const clang::CXXOperatorCallExpr *op =
- llvm::dyn_cast<clang::CXXOperatorCallExpr>(&ExprNode)) {
- return op->getNumArgs() == 2 &&
- op->getOperator() != clang::OO_PlusPlus &&
- op->getOperator() != clang::OO_MinusMinus &&
- op->getOperator() != clang::OO_Call &&
- op->getOperator() != clang::OO_Subscript;
- }
- return false;
-}
-
-// Format a pointer to an expression: prefix with '*' but simplify
-// when it already begins with '&'. Return empty string on failure.
-std::string FormatDereference(const clang::SourceManager &SourceManager,
- const clang::Expr &ExprNode) {
- if (const clang::UnaryOperator *Op =
- llvm::dyn_cast<clang::UnaryOperator>(&ExprNode)) {
- if (Op->getOpcode() == clang::UO_AddrOf) {
- // Strip leading '&'.
- return GetText(SourceManager, *Op->getSubExpr()->IgnoreParens());
- }
- }
- const std::string Text = GetText(SourceManager, ExprNode);
- if (Text.empty()) return std::string();
- // Add leading '*'.
- if (NeedParensAfterUnaryOperator(ExprNode)) {
- return std::string("*(") + Text + ")";
- }
- return std::string("*") + Text;
-}
-
-class FixCStrCall : public clang::tooling::MatchFinder::MatchCallback {
- public:
- virtual void Run(const clang::tooling::MatchFinder::MatchResult &Result) {
- const clang::CallExpr *Call =
- Result.Nodes.GetStmtAs<clang::CallExpr>("call");
- const clang::Expr *Arg =
- Result.Nodes.GetStmtAs<clang::Expr>("arg");
- const bool Arrow =
- Result.Nodes.GetStmtAs<clang::MemberExpr>("member")->isArrow();
- // Replace the "call" node with the "arg" node, prefixed with '*'
- // if the call was using '->' rather than '.'.
- const std::string ArgText = Arrow ?
- FormatDereference(*Result.SourceManager, *Arg) :
- GetText(*Result.SourceManager, *Arg);
- if (ArgText.empty()) return;
-
- llvm::outs() <<
- Result.SourceManager->getBufferName(Call->getLocStart(), NULL) << ":";
- PrintPosition(llvm::outs(), *Result.SourceManager, *Call);
- llvm::outs() << ":" << ArgText << "\n";
- }
-};
-
-const char *StringConstructor =
- "::std::basic_string<char, std::char_traits<char>, std::allocator<char> >"
- "::basic_string";
-
-const char *StringCStrMethod =
- "::std::basic_string<char, std::char_traits<char>, std::allocator<char> >"
- "::c_str";
-
-int main(int argc, char **argv) {
- clang::tooling::ClangTool Tool(argc, argv);
- clang::tooling::MatchFinder finder;
- finder.AddMatcher(
- ConstructorCall(
- HasDeclaration(Method(HasName(StringConstructor))),
- ArgumentCountIs(2),
- // The first argument must have the form x.c_str() or p->c_str()
- // where the method is string::c_str(). We can use the copy
- // constructor of string instead (or the compiler might share
- // the string object).
- HasArgument(
- 0,
- Id("call", Call(
- Callee(Id("member", MemberExpression())),
- Callee(Method(HasName(StringCStrMethod))),
- On(Id("arg", Expression()))))),
- // The second argument is the alloc object which must not be
- // present explicitly.
- HasArgument(
- 1,
- DefaultArgument())), new FixCStrCall);
- finder.AddMatcher(
- ConstructorCall(
- // Implicit constructors of these classes are overloaded
- // wrt. string types and they internally make a StringRef
- // referring to the argument. Passing a string directly to
- // them is preferred to passing a char pointer.
- HasDeclaration(Method(AnyOf(
- HasName("::llvm::StringRef::StringRef"),
- HasName("::llvm::Twine::Twine")))),
- ArgumentCountIs(1),
- // The only argument must have the form x.c_str() or p->c_str()
- // where the method is string::c_str(). StringRef also has
- // a constructor from string which is more efficient (avoids
- // strlen), so we can construct StringRef from the string
- // directly.
- HasArgument(
- 0,
- Id("call", Call(
- Callee(Id("member", MemberExpression())),
- Callee(Method(HasName(StringCStrMethod))),
- On(Id("arg", Expression())))))),
- new FixCStrCall);
- return Tool.Run(finder.NewFrontendActionFactory());
-}
-
diff --git a/examples/Tooling/replace.py b/examples/Tooling/replace.py
deleted file mode 100755
index a738dea70c..0000000000
--- a/examples/Tooling/replace.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-
-#===- replace.py - Applying code rewrites --------------------*- python -*--===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-#
-# This script applies the rewrites generated by replace-cstr-calls on a source
-# tree.
-#
-# Usage:
-# ./replace.py < /path/to/replace-cstr-calls-output
-#
-#===------------------------------------------------------------------------===#
-
-import fileinput
-import re
-import sys
-
-for line in sys.stdin.readlines():
- # The format is:
- # <file>:<start_line>:<start_column>:<end_line>:<end_column>:<replacement>
- # FIXME: This currently does not support files with colons, we'll need to
- # figure out a format when we implement more refactoring support.
- match = re.match(r'(.*):(\d+):(\d+):(\d+):(\d+):(.*)$', line)
- if match is not None:
- file_name = match.group(1)
- start_line, start_column = int(match.group(2)), int(match.group(3))
- end_line, end_column = int(match.group(4)), int(match.group(5))
- replacement = match.group(6)
- if start_line != end_line:
- print ('Skipping match "%s": only single line ' +
- 'replacements are supported') % line.strip()
- continue
- try:
- replace_file = fileinput.input(file_name, inplace=1)
- for replace_line in replace_file:
- # FIXME: Looping over the file for each replacement is both inefficient
- # and incorrect if replacements add or remove lines.
- if replace_file.lineno() == start_line:
- sys.stdout.write(replace_line[:start_column-1] + replacement +
- replace_line[end_column:])
- else:
- sys.stdout.write(replace_line)
- except OSError, e:
- print 'Cannot open %s for editing' % file_name
diff --git a/include/clang/Tooling/ASTMatchers.h b/include/clang/Tooling/ASTMatchers.h
deleted file mode 100644
index 74b94c967e..0000000000
--- a/include/clang/Tooling/ASTMatchers.h
+++ /dev/null
@@ -1,1735 +0,0 @@
-//===--- ASTMatchers.h - Structural query framework -------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a framework of AST matchers that can be used to express
-// structural queries on the AST representing C++ code.
-//
-// The general idea is to construct a matcher expression that describes a
-// subtree match on the AST. Next, a callback that is executed every time the
-// expression matches is registered, and the matcher is run over the AST of
-// some code. Matched subexpressions can be bound to string IDs and easily
-// be accessed from the registered callback. The callback can than use the
-// AST nodes that the subexpressions matched on to output information about
-// the match or construct changes that can be applied to the code.
-//
-// Example:
-// class HandleMatch : public clang::tooling::MatchFinder::MatchCallback {
-// public:
-// virtual void Run(const clang::tooling::MatchFinder::MatchResult &Result) {
-// const clang::CXXRecordDecl *Class =
-// Result.Nodes.GetDeclAs<clang::CXXRecordDecl>("id");
-// ...
-// }
-// };
-//
-// int main(int argc, char **argv) {
-// ClangTool Tool(argc, argv);
-// MatchFinder finder;
-// finder.AddMatcher(Id("id", Class(HasName("::a_namespace::AClass"))),
-// new HandleMatch);
-// return Tool.Run(finder.NewFrontendActionFactory());
-// }
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_AST_MATCHERS_H
-#define LLVM_CLANG_TOOLING_AST_MATCHERS_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Tooling/VariadicFunction.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/type_traits.h"
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-/// FIXME: Move into the llvm support library.
-template <bool> struct CompileAssert {};
-#define COMPILE_ASSERT(Expr, Msg) \
- typedef CompileAssert<(bool(Expr))> Msg[bool(Expr) ? 1 : -1]
-
-namespace clang {
-
-class FrontendAction;
-class SourceManager;
-
-namespace tooling {
-
-class FrontendActionFactory;
-class BoundNodesBuilder;
-
-/// Contains a mapping from IDs to nodes bound to those IDs and provides
-/// convenient access to those nodes.
-class BoundNodes {
- public:
- BoundNodes() {}
-
- /// Create BoundNodes from a pre-filled map of bindings.
- BoundNodes(const std::map<std::string, const clang::Decl*> &DeclBindings,
- const std::map<std::string, const clang::Stmt*> &StmtBindings)
- : DeclBindings(DeclBindings), StmtBindings(StmtBindings) {}
-
- /// Returns the node bound to the specified id if the id was bound to a node
- /// and that node can be converted into the specified type. Returns NULL
- /// otherwise.
- /// FIXME: We'll need one of those for every base type.
- template <typename T>
- const T *GetDeclAs(const std::string &ID) const {
- return GetNodeAs<T>(DeclBindings, ID);
- }
- template <typename T>
- const T *GetStmtAs(const std::string &ID) const {
- return GetNodeAs<T>(StmtBindings, ID);
- }
-
- /// Adds all bound nodes to bound_nodes_builder.
- void CopyTo(BoundNodesBuilder *CopyToBuilder) const;
-
- private:
- template <typename T, typename MapT>
- const T *GetNodeAs(const MapT &Bindings, const std::string &ID) const {
- typename MapT::const_iterator It = Bindings.find(ID);
- if (It == Bindings.end()) {
- return NULL;
- }
- return llvm::dyn_cast<T>(It->second);
- }
-
- std::map<std::string, const clang::Decl*> DeclBindings;
- std::map<std::string, const clang::Stmt*> StmtBindings;
-}; // class BoundNodes
-
-/// Creates BoundNodes objects.
-class BoundNodesBuilder {
- public:
- BoundNodesBuilder() {}
-
- /// Add a binding from 'ID' to 'Node'.
- /// FIXME: Add overloads for all AST base types.
- void SetBinding(const std::string &ID, const clang::Decl *Node) {
- DeclBindings[ID] = Node;
- }
- void SetBinding(const std::string &ID, const clang::Stmt *Node) {
- StmtBindings[ID] = Node;
- }
-
- /// Returns a BoundNodes object containing all current bindings.
- BoundNodes Build() const {
- return BoundNodes(DeclBindings, StmtBindings);
- }
-
- private:
- BoundNodesBuilder(const BoundNodesBuilder&); // DO NOT IMPLEMENT
- void operator=(const BoundNodesBuilder&); // DO NOT IMPLEMENT
-
- std::map<std::string, const clang::Decl*> DeclBindings;
- std::map<std::string, const clang::Stmt*> StmtBindings;
-};
-
-inline void BoundNodes::CopyTo(BoundNodesBuilder *CopyToBuilder) const {
- for (std::map<std::string, const clang::Decl*>::const_iterator
- It = DeclBindings.begin(), End = DeclBindings.end();
- It != End; ++It) {
- CopyToBuilder->SetBinding(It->first, It->second);
- }
- /// FIXME: Pull out method.
- for (std::map<std::string, const clang::Stmt*>::const_iterator
- It = StmtBindings.begin(), End = StmtBindings.end();
- It != End; ++It) {
- CopyToBuilder->SetBinding(It->first, It->second);
- }
-}
-
-class ASTMatchFinder;
-
-/// Generic interface for matchers on an AST node of type T. Implement
-/// this if your matcher may need to inspect the children or
-/// descendants of the node or bind matched nodes to names. If you are
-/// writing a simple matcher that only inspects properties of the
-/// current node and doesn't care about its children or descendants,
-/// implement SingleNodeMatcherInterface instead.
-template <typename T>
-class MatcherInterface : public llvm::RefCountedBaseVPTR {
- public:
- virtual ~MatcherInterface() {}
-
- /// Returns true if 'Node' can be matched.
- /// May bind 'Node' to an ID via 'Builder', or recurse into
- /// the AST via 'Finder'.
- virtual bool Matches(
- const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const = 0;
-};
-
-/// Interface for matchers that only evaluate properties on a single node.
-template <typename T>
-class SingleNodeMatcherInterface : public MatcherInterface<T> {
- public:
- /// Returns true if the matcher matches the provided node. A subclass
- /// must implement this instead of Matches().
- virtual bool MatchesNode(const T &Node) const = 0;
-
- private:
- /// Implements MatcherInterface::Matches.
- virtual bool Matches(const T &Node,
- ASTMatchFinder * /* Finder */,
- BoundNodesBuilder * /* Builder */) const {
- return MatchesNode(Node);
- }
-};
-
-/// Wrapper of a MatcherInterface<T> *that allows copying.
-///
-/// A Matcher<Base> can be used anywhere a Matcher<Derived> is
-/// required. This establishes an is-a relationship which is reverse
-/// to the AST hierarchy. In other words, Matcher<T> is contravariant
-/// with respect to T. The relationship is built via a type conversion
-/// operator rather than a type hierarchy to be able to templatize the
-/// type hierarchy instead of spelling it out.
-template <typename T>
-class Matcher {
- public:
- /// Takes ownership of the provided implementation pointer.
- explicit Matcher(MatcherInterface<T> *Implementation)
- : Implementation(Implementation) {}
-
- /// Forwards the call to the underlying MatcherInterface<T> pointer.
- bool Matches(
- const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return Implementation->Matches(Node, Finder, Builder);
- }
-
- /// Implicitly converts this object to a Matcher<Derived>; requires
- /// Derived to be derived from T.
- template <typename Derived>
- operator Matcher<Derived>() const {
- return Matcher<Derived>(new ImplicitCastMatcher<Derived>(*this));
- }
-
- /// Returns an ID that uniquely identifies the matcher.
- uint64_t GetID() const {
- /// FIXME: Document the requirements this imposes on matcher
- /// implementations (no new() implementation_ during a Matches()).
- return reinterpret_cast<uint64_t>(Implementation.getPtr());
- }
-
- private:
- /// Allows conversion from Matcher<T> to Matcher<Derived> if Derived
- /// is derived from T.
- template <typename Derived>
- class ImplicitCastMatcher : public MatcherInterface<Derived> {
- public:
- explicit ImplicitCastMatcher(const Matcher<T> &From)
- : From(From) {}
-
- virtual bool Matches(
- const Derived &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return From.Matches(Node, Finder, Builder);
- }
-
- private:
- const Matcher<T> From;
- };
-
- llvm::IntrusiveRefCntPtr< MatcherInterface<T> > Implementation;
-}; // class Matcher
-
-/// A convenient helper for creating a Matcher<T> without specifying
-/// the template type argument.
-template <typename T>
-inline Matcher<T> MakeMatcher(MatcherInterface<T> *Implementation) {
- return Matcher<T>(Implementation);
-}
-
-/// Matches declarations for QualType and CallExpr. Type argument
-/// DeclMatcherT is required by PolymorphicMatcherWithParam1 but not
-/// actually used.
-template <typename T, typename DeclMatcherT>
-class HasDeclarationMatcher : public MatcherInterface<T> {
- COMPILE_ASSERT((llvm::is_same< DeclMatcherT, Matcher<clang::Decl> >::value),
- instantiated_with_wrong_types);
- public:
- explicit HasDeclarationMatcher(const Matcher<clang::Decl> &InnerMatcher)
- : InnerMatcher(InnerMatcher) {}
-
- virtual bool Matches(
- const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return MatchesSpecialized(Node, Finder, Builder);
- }
-
- private:
- /// Extracts the CXXRecordDecl of a QualType and returns whether the inner
- /// matcher matches on it.
- bool MatchesSpecialized(
- const clang::QualType &Node, ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- /// FIXME: Add other ways to convert...
- clang::CXXRecordDecl *NodeAsRecordDecl = Node->getAsCXXRecordDecl();
- return NodeAsRecordDecl != NULL &&
- InnerMatcher.Matches(*NodeAsRecordDecl, Finder, Builder);
- }
-
- /// Extracts the Decl of the callee of a CallExpr and returns whether the
- /// inner matcher matches on it.
- bool MatchesSpecialized(
- const clang::CallExpr &Node, ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- const clang::Decl *NodeAsDecl = Node.getCalleeDecl();
- return NodeAsDecl != NULL &&
- InnerMatcher.Matches(*NodeAsDecl, Finder, Builder);
- }
-
- /// Extracts the Decl of the constructor call and returns whether the inner
- /// matcher matches on it.
- bool MatchesSpecialized(
- const clang::CXXConstructExpr &Node, ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- const clang::Decl *NodeAsDecl = Node.getConstructor();
- return NodeAsDecl != NULL &&
- InnerMatcher.Matches(*NodeAsDecl, Finder, Builder);
- }
-
- const Matcher<clang::Decl> InnerMatcher;
-};
-
-/// IsBaseType<T>::value is true if T is a "base" type in the AST
-/// node class hierarchies (i.e. if T is Decl, Stmt, or QualType).
-template <typename T>
-struct IsBaseType {
- static const bool value = (llvm::is_same<T, clang::Decl>::value ||
- llvm::is_same<T, clang::Stmt>::value ||
- llvm::is_same<T, clang::QualType>::value);
-};
-template <typename T>
-const bool IsBaseType<T>::value;
-
-/// Interface that can match any AST base node type and contains default
-/// implementations returning false.
-class UntypedBaseMatcher {
- public:
- virtual ~UntypedBaseMatcher() {}
-
- virtual bool Matches(
- const clang::Decl &DeclNode, ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return false;
- }
- virtual bool Matches(
- const clang::QualType &TypeNode, ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return false;
- }
- virtual bool Matches(
- const clang::Stmt &StmtNode, ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return false;
- }
-
- /// Returns a unique ID for the matcher.
- virtual uint64_t GetID() const = 0;
-};
-
-/// An UntypedBaseMatcher that overwrites the Matches(...) method for node
-/// type T. T must be an AST base type.
-template <typename T>
-class TypedBaseMatcher : public UntypedBaseMatcher {
- COMPILE_ASSERT(IsBaseType<T>::value,
- typed_base_matcher_can_only_be_used_with_base_type);
- public:
- explicit TypedBaseMatcher(const Matcher<T> &InnerMatcher)
- : InnerMatcher(InnerMatcher) {}
-
- using UntypedBaseMatcher::Matches;
- /// Implements UntypedBaseMatcher::Matches. Since T is guaranteed to
- /// be a "base" AST node type, this method is guaranteed to override
- /// one of the Matches() methods from UntypedBaseMatcher.
- virtual bool Matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return InnerMatcher.Matches(Node, Finder, Builder);
- }
-
- /// Implements UntypedBaseMatcher::GetID.
- virtual uint64_t GetID() const {
- return InnerMatcher.GetID();
- }
-
- private:
- Matcher<T> InnerMatcher;
-};
-
-/// Interface that allows matchers to traverse the AST.
-/// This provides two entry methods for each base node type in the AST:
-/// - MatchesChildOf:
-/// Matches a matcher on every child node of the given node. Returns true
-/// if at least one child node could be matched.
-/// - MatchesDescendantOf:
-/// Matches a matcher on all descendant nodes of the given node. Returns true
-/// if at least one descendant matched.
-class ASTMatchFinder {
- public:
- /// Defines how we descend a level in the AST when we pass
- /// through expressions.
- enum TraversalMethod {
- /// Will traverse any child nodes.
- kAsIs,
- /// Will not traverse implicit casts and parentheses.
- kIgnoreImplicitCastsAndParentheses
- };
-
- virtual ~ASTMatchFinder() {}
-
- /// Returns true if the given class is directly or indirectly derived
- /// from a base type with the given name. A class is considered to
- /// be also derived from itself.
- virtual bool ClassIsDerivedFrom(const clang::CXXRecordDecl *Declaration,
- const std::string &BaseName) const = 0;
-
- // FIXME: Implement for other base nodes.
- virtual bool MatchesChildOf(const clang::Decl &DeclNode,
- const UntypedBaseMatcher &BaseMatcher,
- BoundNodesBuilder *Builder,
- TraversalMethod Traverse) = 0;
- virtual bool MatchesChildOf(const clang::Stmt &StmtNode,
- const UntypedBaseMatcher &BaseMatcher,
- BoundNodesBuilder *Builder,
- TraversalMethod Traverse) = 0;
-
- virtual bool MatchesDescendantOf(const clang::Decl &DeclNode,
- const UntypedBaseMatcher &BaseMatcher,
- BoundNodesBuilder *Builder) = 0;
- virtual bool MatchesDescendantOf(const clang::Stmt &StmtNode,
- const UntypedBaseMatcher &BaseMatcher,
- BoundNodesBuilder *Builder) = 0;
-};
-
-/// Converts a Matcher<T> to a matcher of desired type To by "adapting"
-/// a To into a T. The ArgumentAdapterT argument specifies how the
-/// adaptation is done. For example:
-///
-/// ArgumentAdaptingMatcher<DynCastMatcher, T>(InnerMatcher);
-/// returns a matcher that can be used where a Matcher<To> is required, if
-/// To and T are in the same type hierarchy, and thus dyn_cast can be
-/// called to convert a To to a T.
-///
-/// FIXME: Make sure all our applications of this class actually require
-/// knowledge about the inner type. DynCastMatcher obviously does, but the
-/// Has *matchers require the inner type solely for COMPILE_ASSERT purposes.
-template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
- typename T>
-class ArgumentAdaptingMatcher {
- public:
- explicit ArgumentAdaptingMatcher(const Matcher<T> &InnerMatcher)
- : InnerMatcher(InnerMatcher) {}
-
- template <typename To>
- operator Matcher<To>() const {
- return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
- }
-
- private:
- const Matcher<T> InnerMatcher;
-};
-
-/// A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be
-/// created from N parameters p1, ..., pN (of type P1, ..., PN) and
-/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
-/// can be constructed.
-///
-/// For example:
-/// - PolymorphicMatcherWithParam0<IsDefinitionMatcher>()
-/// creates an object that can be used as a Matcher<T> for any type T
-/// where an IsDefinitionMatcher<T>() can be constructed.
-/// - PolymorphicMatcherWithParam1<ValueEqualsMatcher, int>(42)
-/// creates an object that can be used as a Matcher<T> for any type T
-/// where a ValueEqualsMatcher<T, int>(42) can be constructed.
-template <template <typename T> class MatcherT>
-class PolymorphicMatcherWithParam0 {
- public:
- template <typename T>
- operator Matcher<T>() const {
- return Matcher<T>(new MatcherT<T>());
- }
-};
-
-template <template <typename T, typename P1> class MatcherT,
- typename P1>
-class PolymorphicMatcherWithParam1 {
- public:
- explicit PolymorphicMatcherWithParam1(const P1 &Param1)
- : Param1(Param1) {}
-
- template <typename T>
- operator Matcher<T>() const {
- return Matcher<T>(new MatcherT<T, P1>(Param1));
- }
-
- private:
- const P1 Param1;
-};
-
-template <template <typename T, typename P1, typename P2> class MatcherT,
- typename P1, typename P2>
-class PolymorphicMatcherWithParam2 {
- public:
- PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2)
- : Param1(Param1), Param2(Param2) {}
-
- template <typename T>
- operator Matcher<T>() const {
- return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2));
- }
-
- private:
- const P1 Param1;
- const P2 Param2;
-};
-
-// FIXME: Alternatively we could also create a IsAMatcher or something
-// that checks that a dyn_cast is possible. This is purely needed for the
-// difference between calling for example:
-// Class()
-// and
-// Class(SomeMatcher)
-// In the second case we need the correct type we were dyn_cast'ed to in order
-// to get the right type for the inner matcher. In the first case we don't need
-// that, but we use the type conversion anyway and insert a TrueMatcher.
-template <typename T>
-class TrueMatcher : public SingleNodeMatcherInterface<T> {
- public:
- virtual bool MatchesNode(const T &Node) const {
- return true;
- }
-};
-
-/// Provides a MatcherInterface<T> for a Matcher<To> that matches if T is
-/// dyn_cast'able into To and the given Matcher<To> matches on the dyn_cast'ed
-/// node.
-template <typename T, typename To>
-class DynCastMatcher : public MatcherInterface<T> {
- public:
- explicit DynCastMatcher(const Matcher<To> &InnerMatcher)
- : InnerMatcher(InnerMatcher) {}
-
- virtual bool Matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- const To *InnerMatchValue = llvm::dyn_cast<To>(&Node);
- return InnerMatchValue != NULL &&
- InnerMatcher.Matches(*InnerMatchValue, Finder, Builder);
- }
-
- private:
- const Matcher<To> InnerMatcher;
-};
-
-/// Enables the user to pass a Matcher<clang::CXXMemberCallExpr> to Call().
-/// FIXME: Alternatives are using more specific methods than Call, like
-/// MemberCall, or not using VariadicFunction for Call and overloading it.
-template <>
-template <>
-inline Matcher<clang::CXXMemberCallExpr>::
-operator Matcher<clang::CallExpr>() const {
- return MakeMatcher(
- new DynCastMatcher<clang::CallExpr, clang::CXXMemberCallExpr>(*this));
-}
-
-/// Matcher<T> that wraps an inner Matcher<T> and binds the matched node to
-/// an ID if the inner matcher matches on the node.
-template <typename T>
-class IdMatcher : public MatcherInterface<T> {
- public:
- /// Creates an IdMatcher that binds to 'ID' if 'InnerMatcher' matches the node.
- IdMatcher(const std::string &ID, const Matcher<T> &InnerMatcher)
- : ID(ID), InnerMatcher(InnerMatcher) {}
-
- virtual bool Matches(
- const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- bool Result = InnerMatcher.Matches(Node, Finder, Builder);
- if (Result) {
- Builder->SetBinding(ID, &Node);
- }
- return Result;
- }
-
- private:
- const std::string ID;
- const Matcher<T> InnerMatcher;
-};
-
-/// Matches nodes of type T that have child nodes of type ChildT for
-/// which a specified child matcher matches. ChildT must be an AST base
-/// type.
-template <typename T, typename ChildT>
-class HasMatcher : public MatcherInterface<T> {
- COMPILE_ASSERT(IsBaseType<ChildT>::value, has_only_accepts_base_type_matcher);
- public:
- explicit HasMatcher(const Matcher<ChildT> &ChildMatcher)
- : ChildMatcher(ChildMatcher) {}
-
- virtual bool Matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return Finder->MatchesChildOf(
- Node, ChildMatcher, Builder,
- ASTMatchFinder::kIgnoreImplicitCastsAndParentheses);
- }
-
- private:
- const TypedBaseMatcher<ChildT> ChildMatcher;
-};
-
-/// Matches nodes of type T if the given Matcher<T> does not match.
-/// Type argument MatcherT is required by PolymorphicMatcherWithParam1
-/// but not actually used. It will always be instantiated with a type
-/// convertible to Matcher<T>.
-template <typename T, typename MatcherT>
-class NotMatcher : public MatcherInterface<T> {
- public:
- explicit NotMatcher(const Matcher<T> &InnerMatcher)
- : InnerMatcher(InnerMatcher) {}
-
- virtual bool Matches(
- const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return !InnerMatcher.Matches(Node, Finder, Builder);
- }
-
- private:
- const Matcher<T> InnerMatcher;
-};
-
-/// Matches nodes of type T for which both provided matchers
-/// match. Type arguments MatcherT1 and MatcherT2 are required by
-/// PolymorphicMatcherWithParam2 but not actually used. They will
-/// always be instantiated with types convertible to Matcher<T>.
-template <typename T, typename MatcherT1, typename MatcherT2>
-class AllOfMatcher : public MatcherInterface<T> {
- public:
- AllOfMatcher(const Matcher<T> &InnerMatcher1, const Matcher<T> &InnerMatcher2)
- : InnerMatcher1(InnerMatcher1), InnerMatcher2(InnerMatcher2) {}
-
- virtual bool Matches(
- const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return InnerMatcher1.Matches(Node, Finder, Builder) &&
- InnerMatcher2.Matches(Node, Finder, Builder);
- }
-
- private:
- const Matcher<T> InnerMatcher1;
- const Matcher<T> InnerMatcher2;
-};
-
-/// Matches nodes of type T for which at least one of the two provided
-/// matchers matches. Type arguments MatcherT1 and MatcherT2 are
-/// required by PolymorphicMatcherWithParam2 but not actually
-/// used. They will always be instantiated with types convertible to
-/// Matcher<T>.
-template <typename T, typename MatcherT1, typename MatcherT2>
-class AnyOfMatcher : public MatcherInterface<T> {
- public:
- AnyOfMatcher(const Matcher<T> &InnerMatcher1, const Matcher<T> &InnerMatcher2)
- : InnerMatcher1(InnerMatcher1), InnertMatcher2(InnerMatcher2) {}
-
- virtual bool Matches(
- const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return InnerMatcher1.Matches(Node, Finder, Builder) ||
- InnertMatcher2.Matches(Node, Finder, Builder);
- }
-
- private:
- const Matcher<T> InnerMatcher1;
- const Matcher<T> InnertMatcher2;
-};
-
-/// Creates a Matcher<T> that matches if
-/// T is dyn_cast'able into InnerT and all inner matchers match.
-template<typename T, typename InnerT>
-Matcher<T> MakeDynCastAllOfComposite(
- const Matcher<InnerT> *const InnerMatchers[], int Count) {
- if (Count == 0) {
- return ArgumentAdaptingMatcher<DynCastMatcher, InnerT>(
- MakeMatcher(new TrueMatcher<InnerT>));
- }
- Matcher<InnerT> InnerMatcher = *InnerMatchers[Count-1];
- for (int I = Count-2; I >= 0; --I) {
- InnerMatcher = MakeMatcher(
- new AllOfMatcher<InnerT, Matcher<InnerT>, Matcher<InnerT> >(
- *InnerMatchers[I], InnerMatcher));
- }
- return ArgumentAdaptingMatcher<DynCastMatcher, InnerT>(InnerMatcher);
-}
-
-/// Matches nodes of type T that have at least one descendant node of
-/// type DescendantT for which the given inner matcher matches.
-/// DescendantT must be an AST base type.
-template <typename T, typename DescendantT>
-class HasDescendantMatcher : public MatcherInterface<T> {
- COMPILE_ASSERT(IsBaseType<DescendantT>::value,
- has_descendant_only_accepts_base_type_matcher);
- public:
- explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
- : DescendantMatcher(DescendantMatcher) {}
-
- virtual bool Matches(
- const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder) const {
- return Finder->MatchesDescendantOf(
- Node, DescendantMatcher, Builder);
- }
-
- private:
- const TypedBaseMatcher<DescendantT> DescendantMatcher;
-};
-
-/// Matches on nodes that have a getValue() method if getValue() equals the
-/// value the ValueEqualsMatcher was constructed with.
-template <typename T, typename ValueT>
-class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
- COMPILE_ASSERT((llvm::is_base_of<clang::CharacterLiteral, T>::value) ||
- (llvm::is_base_of<clang::CXXBoolLiteralExpr, T>::value) ||
- (llvm::is_base_of<clang::FloatingLiteral, T>::value) ||
- (llvm::is_base_of<clang::IntegerLiteral, T>::value),
- the_node_must_have_a_getValue_method);
- public:
- explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
- : ExpectedValue(ExpectedValue) {}
-
- virtual bool MatchesNode(const T &Node) const {
- return Node.getValue() == ExpectedValue;
- }
-
- private:
- const ValueT ExpectedValue;
-};
-
-template <typename T>
-class IsDefinitionMatcher : public SingleNodeMatcherInterface<T> {
- COMPILE_ASSERT((llvm::is_base_of<clang::TagDecl, T>::value) ||
- (llvm::is_base_of<clang::VarDecl, T>::value) ||
- (llvm::is_base_of<clang::FunctionDecl, T>::value),
- is_definition_requires_isThisDeclarationADefinition_method);
- public:
- virtual bool MatchesNode(const T &Node) const {
- return Node.isThisDeclarationADefinition();
- }
-};
-
-class IsArrowMatcher : public SingleNodeMatcherInterface<clang::MemberExpr> {
- public:
- virtual bool MatchesNode(const clang::MemberExpr &Node) const {
- return Node.isArrow();
- }
-};
-
-/// A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
-/// variadic functor that takes a list of Matcher<TargetT> and returns
-/// a Matcher<SourceT> that dyn_casts its argument to TargetT.
-template <typename SourceT, typename TargetT>
-class VariadicDynCastAllOfMatcher
- : public internal::VariadicFunction<
- Matcher<SourceT>, Matcher<TargetT>,
- MakeDynCastAllOfComposite<SourceT, TargetT> > {
- public:
- VariadicDynCastAllOfMatcher() {}
-};
-
-/// AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
-///
-/// defines a single-parameter function named DefineMatcher() that returns a
-/// Matcher<Type> object. The code between the curly braces has access
-/// to the following variables:
-///
-/// Node: the AST node being matched; its type is Type.
-/// Param: the parameter passed to the function; its type
-/// is ParamType.
-/// Finder: an ASTMatchFinder*.
-/// Builder: a BoundNodesBuilder*.
-///
-/// The code should return true if 'Node' matches.
-#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \
- class matcher_internal_##DefineMatcher##Matcher \
- : public MatcherInterface<Type> { \
- public: \
- explicit matcher_internal_##DefineMatcher##Matcher( \
- const ParamType &A##Param) : Param(A##Param) {} \
- virtual bool Matches( \
- const Type &Node, ASTMatchFinder *Finder, \
- BoundNodesBuilder *Builder) const; \
- private: \
- const ParamType Param; \
- }; \
- inline Matcher<Type> DefineMatcher(const ParamType &Param) { \
- return MakeMatcher(new matcher_internal_##DefineMatcher##Matcher(Param)); \
- } \
- inline bool matcher_internal_##DefineMatcher##Matcher::Matches( \
- const Type &Node, ASTMatchFinder *Finder, \
- BoundNodesBuilder *Builder) const
-
-/// AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2)
-/// { ... }
-///
-/// defines a two-parameter function named DefineMatcher() that returns a
-/// Matcher<Type> object. The code between the curly braces has access
-/// to the following variables:
-///
-/// Node: the AST node being matched; its type is Type.
-/// Param1, Param2: the parameters passed to the function; their types
-/// are ParamType1 and ParamType2.
-/// Finder: an ASTMatchFinder*.
-/// Builder: a BoundNodesBuilder*.
-///
-/// The code should return true if 'Node' matches.
-#define AST_MATCHER_P2( \
- Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) \
- class matcher_internal_##DefineMatcher##Matcher \
- : public MatcherInterface<Type> { \
- public: \
- matcher_internal_##DefineMatcher##Matcher( \
- const ParamType1 &A##Param1, const ParamType2 &A##Param2) \
- : Param1(A##Param1), Param2(A##Param2) {} \
- virtual bool Matches( \
- const Type &Node, ASTMatchFinder *Finder, \
- BoundNodesBuilder *Builder) const; \
- private: \
- const ParamType1 Param1; \
- const ParamType2 Param2; \
- }; \
- inline Matcher<Type> DefineMatcher( \
- const ParamType1 &Param1, const ParamType2 &Param2) { \
- return MakeMatcher(new matcher_internal_##DefineMatcher##Matcher( \
- Param1, Param2)); \
- } \
- inline bool matcher_internal_##DefineMatcher##Matcher::Matches( \
- const Type &Node, ASTMatchFinder *Finder, \
- BoundNodesBuilder *Builder) const
-
-/// AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
-///
-/// defines a single-parameter function named DefineMatcher() that is
-/// polymorphic in the return type. The variables are the same as for
-/// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
-/// of the matcher Matcher<NodeType> returned by the function matcher().
-///
-/// FIXME: Pull out common code with above macro?
-#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) \
- template <typename NodeType, typename ParamT> \
- class matcher_internal_##DefineMatcher##Matcher \
- : public MatcherInterface<NodeType> { \
- public: \
- explicit matcher_internal_##DefineMatcher##Matcher( \
- const ParamType &A##Param) : Param(A##Param) {} \
- virtual bool Matches( \
- const NodeType &Node, ASTMatchFinder *Finder, \
- BoundNodesBuilder *Builder) const; \
- private: \
- const ParamType Param; \
- }; \
- inline PolymorphicMatcherWithParam1< \
- matcher_internal_##DefineMatcher##Matcher, \
- ParamType > \
- DefineMatcher(const ParamType &Param) { \
- return PolymorphicMatcherWithParam1< \
- matcher_internal_##DefineMatcher##Matcher, \
- ParamType >(Param); \
- } \
- template <typename NodeType, typename ParamT> \
- bool matcher_internal_##DefineMatcher##Matcher<NodeType, ParamT>::Matches( \
- const NodeType &Node, ASTMatchFinder *Finder, \
- BoundNodesBuilder *Builder) const
-
-/// AST_POLYMORPHIC_MATCHER_P2(
-/// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
-///
-/// defines a two-parameter function named matcher() that is polymorphic in
-/// the return type. The variables are the same as for AST_MATCHER_P2, with the
-/// addition of NodeType, which specifies the node type of the matcher
-/// Matcher<NodeType> returned by the function DefineMatcher().
-#define AST_POLYMORPHIC_MATCHER_P2( \
- DefineMatcher, ParamType1, Param1, ParamType2, Param2) \
- template <typename NodeType, typename ParamT1, typename ParamT2> \
- class matcher_internal_##DefineMatcher##Matcher \
- : public MatcherInterface<NodeType> { \
- public: \
- matcher_internal_##DefineMatcher##Matcher( \
- const ParamType1 &A##Param1, const ParamType2 &A##Param2) \
- : Param1(A##Param1), Param2(A##Param2) {} \
- virtual bool Matches( \
- const NodeType &Node, ASTMatchFinder *Finder, \
- BoundNodesBuilder *Builder) const; \
- private: \
- const ParamType1 Param1; \
- const ParamType2 Param2; \
- }; \
- inline PolymorphicMatcherWithParam2< \
- matcher_internal_##DefineMatcher##Matcher, \
- ParamType1, ParamType2 > \
- DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \
- return PolymorphicMatcherWithParam2< \
- matcher_internal_##DefineMatcher##Matcher, \
- ParamType1, ParamType2 >( \
- Param1, Param2); \
- } \
- template <typename NodeType, typename ParamT1, typename ParamT2> \
- bool matcher_internal_##DefineMatcher##Matcher< \
- NodeType, ParamT1, ParamT2>::Matches( \
- const NodeType &Node, ASTMatchFinder *Finder, \
- BoundNodesBuilder *Builder) const
-
-namespace match {
-
-typedef Matcher<clang::Decl> DeclarationMatcher;
-typedef Matcher<clang::QualType> TypeMatcher;
-typedef Matcher<clang::Stmt> StatementMatcher;
-
-/// Matches C++ class declarations.
-///
-/// Example matches X, Z
-/// class X;
-/// template<class T> class Z {};
-const VariadicDynCastAllOfMatcher<clang::Decl, clang::CXXRecordDecl> Class;
-
-/// Matches method declarations.
-///
-/// Example matches y
-/// class X { void y() };
-const VariadicDynCastAllOfMatcher<clang::Decl, clang::CXXMethodDecl> Method;
-
-/// Matches variable declarations.
-///
-/// Example matches a
-/// int a;
-const VariadicDynCastAllOfMatcher<clang::Decl, clang::VarDecl> Variable;
-
-/// Matches member expressions.
-///
-/// Given
-/// class Y {
-/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
-/// int a; static int b;
-/// };
-/// MemberExpression()
-/// matches this->x, x, y.x, a, this->b
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::MemberExpr>
-MemberExpression;
-
-/// Matches call expressions.
-///
-/// Example matches x.y()
-/// X x;
-/// x.y();
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::CallExpr> Call;
-
-/// Matches constructor call expressions (including implicit ones).
-///
-/// Example matches string(ptr, n) and ptr within arguments of f
-/// (matcher = ConstructorCall())
-/// void f(const string &a, const string &b);
-/// char *ptr;
-/// int n;
-/// f(string(ptr, n), ptr);
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::CXXConstructExpr>
-ConstructorCall;
-
-/// Matches the value of a default argument at the call site.
-///
-/// Example matches the CXXDefaultArgExpr placeholder inserted for the
-/// default value of the second parameter in the call expression f(42)
-/// (matcher = DefaultArgument())
-/// void f(int x, int y = 0);
-/// f(42);
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::CXXDefaultArgExpr>
-DefaultArgument;
-
-/// Matches overloaded operator calls.
-/// Note that if an operator isn't overloaded, it won't match. Instead, use
-/// BinaryOperator matcher.
-/// Currently it does not match operators such as new delete.
-/// FIXME: figure out why these do not match?
-///
-/// Example matches both operator<<((o << b), c) and operator<<(o, b)
-/// (matcher = OverloadedOperatorCall())
-/// ostream &operator<< (ostream &out, int i) { };
-/// ostream &o; int b = 1, c = 1;
-/// o << b << c;
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::CXXOperatorCallExpr>
-OverloadedOperatorCall;
-
-/// Matches expressions.
-///
-/// Example matches x()
-/// void f() { x(); }
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::Expr> Expression;
-
-/// Matches expressions that refer to declarations.
-///
-/// Example matches x in if (x)
-/// bool x;
-/// if (x) {}
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::DeclRefExpr>
-DeclarationReference;
-
-/// Matches if statements.
-///
-/// Example matches 'if (x) {}'
-/// if (x) {}
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::IfStmt> If;
-
-/// Matches for statements.
-///
-/// Example matches 'for (;;) {}'
-/// for (;;) {}
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::ForStmt> For;
-
-/// Matches compound statements.
-///
-/// Example matches '{}' and '{{}}'in 'for (;;) {{}}'
-/// for (;;) {{}}
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::CompoundStmt>
-CompoundStatement;
-
-/// Matches bool literals.
-///
-/// Example matches true
-/// true
-const VariadicDynCastAllOfMatcher<clang::Expr, clang::CXXBoolLiteralExpr>
-BoolLiteral;
-
-/// Matches string literals (also matches wide string literals).
-///
-/// Example matches "abcd", L"abcd"
-/// char *s = "abcd"; wchar_t *ws = L"abcd"
-const VariadicDynCastAllOfMatcher<clang::Expr, clang::StringLiteral>
-StringLiteral;
-
-/// Matches character literals (also matches wchar_t).
-/// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
-/// though.
-///
-/// Example matches 'a', L'a'
-/// char ch = 'a'; wchar_t chw = L'a';
-const VariadicDynCastAllOfMatcher<clang::Expr, clang::CharacterLiteral>
-CharacterLiteral;
-
-/// Matches integer literals of all sizes / encodings.
-/// Not matching character-encoded integers such as L'a'.
-///
-/// Example matches 1, 1L, 0x1, 1U
-const VariadicDynCastAllOfMatcher<clang::Expr, clang::IntegerLiteral>
-IntegerLiteral;
-
-/// Matches binary operator expressions.
-///
-/// Example matches a || b
-/// !(a || b)
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::BinaryOperator>
-BinaryOperator;
-
-/// Matches unary operator expressions.
-///
-/// Example matches !a
-/// !a || b
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::UnaryOperator>
-UnaryOperator;
-
-/// Matches conditional operator expressions.
-///
-/// Example matches a ? b : c
-/// (a ? b : c) + 42
-const VariadicDynCastAllOfMatcher<clang::Stmt, clang::ConditionalOperator>
-ConditionalOperator;
-
-template<typename C1, typename C2>
-PolymorphicMatcherWithParam2<AnyOfMatcher, C1, C2>
-AnyOf(const C1 &P1, const C2 &P2) {
- return PolymorphicMatcherWithParam2< AnyOfMatcher, C1, C2 >(P1, P2);
-}
-
-template<typename C1, typename C2, typename C3>
-PolymorphicMatcherWithParam2<AnyOfMatcher, C1,
- PolymorphicMatcherWithParam2<AnyOfMatcher, C2, C3> >
-AnyOf(const C1 &P1, const C2 &P2, const C3 &P3) {
- return AnyOf(P1, AnyOf(P2, P3));
-}
-
-template<typename C1, typename C2, typename C3, typename C4>
-PolymorphicMatcherWithParam2<AnyOfMatcher, C1,
- PolymorphicMatcherWithParam2<AnyOfMatcher, C2,
- PolymorphicMatcherWithParam2<AnyOfMatcher, C3, C4> > >
-AnyOf(const C1 &P1, const C2 &P2, const C3 &P3, const C4 &P4) {
- return AnyOf(P1, AnyOf(P2, AnyOf(P3, P4)));
-}
-
-template<typename C1, typename C2>
-PolymorphicMatcherWithParam2<AllOfMatcher, C1, C2>
-AllOf(const C1 &P1, const C2 &P2) {
- return PolymorphicMatcherWithParam2<AllOfMatcher, C1, C2>(P1, P2);
-}
-
-/// Matches NamedDecl nodes that have the specified name. Supports specifying
-/// enclosing namespaces or classes by prefixing the name with '<enclosing>::'.
-/// Does not match typedefs of an underlying type with the given name.
-///
-/// Example matches X (name == "X")
-/// class X;
-///
-/// Example matches X (name is one of "::a::b::X", "a::b::X", "b::X", "X")
-/// namespace a { namespace b { class X; } }
-AST_MATCHER_P(clang::NamedDecl, HasName, std::string, Name) {
- assert(!Name.empty());
- const std::string FullNameString = "::" + Node.getQualifiedNameAsString();
- const llvm::StringRef FullName = FullNameString;
- const llvm::StringRef Pattern = Name;
- if (Pattern.startswith("::")) {
- return FullName == Pattern;
- } else {
- return FullName.endswith(("::" + Pattern).str());
- }
-}
-
-/// Matches overloaded operator name given in strings without the "operator"
-/// prefix, such as "<<", for OverloadedOperatorCall's.
-///
-/// Example matches a << b
-/// (matcher == OverloadedOperatorCall(HasOverloadedOperatorName("<<")))
-/// a << b;
-/// c && d; // assuming both operator<<
-/// // and operator&& are overloaded somewhere.
-AST_MATCHER_P(clang::CXXOperatorCallExpr,
- HasOverloadedOperatorName, std::string, Name) {
- return clang::getOperatorSpelling(Node.getOperator()) == Name;
-}
-
-/// Matches C++ classes that are directly or indirectly derived from
-/// the given base class. Note that a class is considered to be also
-/// derived from itself. The parameter specified the name of the base
-/// type (either a class or a typedef), and does not allow structural
-/// matches for namespaces or template type parameters.
-///
-/// Example matches X, Y, Z, C (base == "X")
-/// class X; // A class is considered to be derived from itself.
-/// class Y : public X {}; // directly derived
-/// class Z : public Y {}; // indirectly derived
-/// typedef X A;
-/// typedef A B;
-/// class C : public B {}; // derived from a typedef of X
-///
-/// In the following example, Bar matches IsDerivedFrom("X"):
-/// class Foo;
-/// typedef Foo X;
-/// class Bar : public Foo {}; // derived from a type that X is a typedef of
-AST_MATCHER_P(clang::CXXRecordDecl, IsDerivedFrom, std::string, Base) {
- assert(!Base.empty());
- return Finder->ClassIsDerivedFrom(&Node, Base);
-}
-
-/// Matches AST nodes that have child AST nodes that match the provided matcher.
-///
-/// Example matches X, Y (matcher = Class(Has(Class(HasName("X")))
-/// class X {}; // Matches X, because X::X is a class of name X inside X.
-/// class Y { class X {}; };
-/// class Z { class Y { class X {}; }; }; // Does not match Z.
-///
-/// ChildT must be an AST base type.
-template <typename ChildT>
-ArgumentAdaptingMatcher<HasMatcher, ChildT> Has(
- const Matcher<ChildT> &ChildMatcher) {
- return ArgumentAdaptingMatcher<HasMatcher, ChildT>(ChildMatcher);
-}
-
-/// Matches AST nodes that have descendant AST nodes that match the provided
-/// matcher.
-///
-/// Example matches X, Y, Z (matcher = Class(HasDescendant(Class(HasName("X")))))
-/// class X {}; // Matches X, because X::X is a class of name X inside X.
-/// class Y { class X {}; };
-/// class Z { class Y { class X {}; }; };
-///
-/// DescendantT must be an AST base type.
-template <typename DescendantT>
-ArgumentAdaptingMatcher<HasDescendantMatcher, DescendantT> HasDescendant(
- const Matcher<DescendantT> &DescendantMatcher) {
- return ArgumentAdaptingMatcher<HasDescendantMatcher, DescendantT>(
- DescendantMatcher);
-}
-
-/// Matches if the provided matcher does not match.
-///
-/// Example matches Y (matcher = Class(Not(HasName("X"))))
-/// class X {};
-/// class Y {};
-template <typename M>
-PolymorphicMatcherWithParam1<NotMatcher, M> Not(const M &InnerMatcher) {
- return PolymorphicMatcherWithParam1<NotMatcher, M>(InnerMatcher);
-}
-
-/// If the provided matcher matches a node, binds the node to 'id'.
-/// FIXME: Add example for accessing it.
-template <typename T>
-Matcher<T> Id(const std::string &ID, const Matcher<T> &InnerMatcher) {
- return Matcher<T>(new IdMatcher<T>(ID, InnerMatcher));
-}
-
-/// Matches a type if the declaration of the type matches the given matcher.
-inline PolymorphicMatcherWithParam1< HasDeclarationMatcher,
- Matcher<clang::Decl> >
- HasDeclaration(const Matcher<clang::Decl> &InnerMatcher) {
- return PolymorphicMatcherWithParam1< HasDeclarationMatcher,
- Matcher<clang::Decl> >(InnerMatcher);
-}
-
-/// Matches on the implicit object argument of a member call expression.
-///
-/// Example matches y.x() (matcher = Call(On(HasType(Class(HasName("Y"))))))
-/// class Y { public: void x(); };
-/// void z() { Y y; y.x(); }",
-///
-/// FIXME: Overload to allow directly matching types?
-AST_MATCHER_P(
- clang::CXXMemberCallExpr, On, Matcher<clang::Expr>, InnerMatcher) {
- const clang::Expr *ExprNode = const_cast<clang::CXXMemberCallExpr&>(Node)
- .getImplicitObjectArgument()
- ->IgnoreParenImpCasts();
- return (ExprNode != NULL &&
- InnerMatcher.Matches(*ExprNode, Finder, Builder));
-}
-
-/// Matches if the call expression's callee expression matches.
-///
-/// Given
-/// class Y { void x() { this->x(); x(); Y y; y.x(); } };
-/// void f() { f(); }
-/// Call(Callee(Expression()))
-/// matches this->x(), x(), y.x(), f()
-/// with Callee(...)
-/// matching this->x, x, y.x, f respectively
-///
-/// Note: Callee cannot take the more general Matcher<clang::Expr> because
-/// this introduces ambiguous overloads with calls to Callee taking a
-/// Matcher<clang::Decl>, as the matcher hierarchy is purely implemented in
-/// terms of implicit casts.
-AST_MATCHER_P(clang::CallExpr, Callee, Matcher<clang::Stmt>, InnerMatcher) {
- const clang::Expr *ExprNode = Node.getCallee();
- return (ExprNode != NULL &&
- InnerMatcher.Matches(*ExprNode, Finder, Builder));
-}
-
-/// Matches if the call expression's callee's declaration matches the given
-/// matcher.
-///
-/// Example matches y.x() (matcher = Call(Callee(Method(HasName("x")))))
-/// class Y { public: void x(); };
-/// void z() { Y y; y.x();
-inline Matcher<clang::CallExpr> Callee(
- const Matcher<clang::Decl> &InnerMatcher) {
- return Matcher<clang::CallExpr>(HasDeclaration(InnerMatcher));
-}
-
-/// Matches if the expression's or declaration's type matches a type matcher.
-///
-/// Example matches x (matcher = Expression(HasType(
-/// HasDeclaration(Class(HasName("X"))))))
-/// and z (matcher = Variable(HasType(
-/// HasDeclaration(Class(HasName("X"))))))
-/// class X {};
-/// void y(X &x) { x; X z; }
-AST_POLYMORPHIC_MATCHER_P(HasType, Matcher<clang::QualType>, InnerMatcher) {
- COMPILE_ASSERT((llvm::is_base_of<clang::Expr, NodeType>::value ||
- llvm::is_base_of<clang::ValueDecl, NodeType>::value),
- instantiated_with_wrong_types);
- return InnerMatcher.Matches(Node.getType(), Finder, Builder);
-}
-
-/// Overloaded to match the declaration of the expression's or value
-/// declaration's type.
-/// In case of a value declaration (for example a variable declaration),
-/// this resolves one layer of indirection. For example, in the value declaration
-/// "X x;", Class(HasName("X")) matches the declaration of X, while
-/// Variable(HasType(Class(HasName("X")))) matches the declaration of x."
-///
-/// Example matches x (matcher = Expression(HasType(Class(HasName("X")))))
-/// and z (matcher = Variable(HasType(Class(HasName("X")))))
-/// class X {};
-/// void y(X &x) { x; X z; }
-inline PolymorphicMatcherWithParam1<matcher_internal_HasTypeMatcher,
- Matcher<clang::QualType> >
-HasType(const Matcher<clang::Decl> &InnerMatcher) {
- return HasType(Matcher<clang::QualType>(HasDeclaration(InnerMatcher)));
-}
-
-/// Matches if the matched type is a pointer type and the pointee type matches
-/// the specified matcher.
-///
-/// Example matches y->x()
-/// (matcher = Call(On(HasType(PointsTo(Class(HasName("Y")))))))
-/// class Y { public: void x(); };
-/// void z() { Y *y; y->x(); }
-AST_MATCHER_P(
- clang::QualType, PointsTo, Matcher<clang::QualType>, InnerMatcher) {
- return (Node->isPointerType() &&
- InnerMatcher.Matches(Node->getPointeeType(), Finder, Builder));
-}
-
-/// Overloaded to match the pointee type's declaration.
-inline Matcher<clang::QualType> PointsTo(
- const Matcher<clang::Decl> &InnerMatcher) {
- return PointsTo(Matcher<clang::QualType>(HasDeclaration(InnerMatcher)));
-}
-
-/// Matches if the matched type is a reference type and the referenced type
-/// matches the specified matcher.
-///
-/// Example matches X &x and const X &y
-/// (matcher = Variable(HasType(References(Class(HasName("X"))))))
-/// class X {
-/// void a(X b) {
-/// X &x = b;
-/// const X &y = b;
-/// };
-AST_MATCHER_P(
- clang::QualType, References, Matcher<clang::QualType>, InnerMatcher) {
- return (Node->isReferenceType() &&
- InnerMatcher.Matches(Node->getPointeeType(), Finder, Builder));
-}
-
-/// Overloaded to match the referenced type's declaration.
-inline Matcher<clang::QualType> References(
- const Matcher<clang::Decl> &InnerMatcher) {
- return References(Matcher<clang::QualType>(HasDeclaration(InnerMatcher)));
-}
-
-AST_MATCHER_P(clang::CXXMemberCallExpr, OnImplicitObjectArgument,
- Matcher<clang::Expr>, InnerMatcher) {
- const clang::Expr *ExprNode =
- const_cast<clang::CXXMemberCallExpr&>(Node).getImplicitObjectArgument();
- return (ExprNode != NULL &&
- InnerMatcher.Matches(*ExprNode, Finder, Builder));
-}
-
-/// Matches if the expression's type either matches the specified matcher, or
-/// is a pointer to a type that matches the InnerMatcher.
-inline Matcher<clang::CallExpr> ThisPointerType(
- const Matcher<clang::QualType> &InnerMatcher) {
- return OnImplicitObjectArgument(
- AnyOf(HasType(InnerMatcher), HasType(PointsTo(InnerMatcher))));
-}
-
-/// Overloaded to match the type's declaration.
-inline Matcher<clang::CallExpr> ThisPointerType(
- const Matcher<clang::Decl> &InnerMatcher) {
- return OnImplicitObjectArgument(
- AnyOf(HasType(InnerMatcher), HasType(PointsTo(InnerMatcher))));
-}
-
-/// Matches a DeclRefExpr that refers to a declaration that matches the specified
-/// matcher.
-///
-/// Example matches x in if(x)
-/// (matcher = DeclarationReference(To(Variable(HasName("x")))))
-/// bool x;
-/// if (x) {}
-AST_MATCHER_P(clang::DeclRefExpr, To, Matcher<clang::Decl>, InnerMatcher) {
- const clang::Decl *DeclNode = Node.getDecl();
- return (DeclNode != NULL &&
- InnerMatcher.Matches(*DeclNode, Finder, Builder));
-}
-
-/// Matches a variable declaration that has an initializer expression that
-/// matches the given matcher.
-///
-/// Example matches x (matcher = Variable(HasInitializer(Call())))
-/// bool y() { return true; }
-/// bool x = y();
-AST_MATCHER_P(
- clang::VarDecl, HasInitializer, Matcher<clang::Expr>, InnerMatcher) {
- const clang::Expr *Initializer = Node.getAnyInitializer();
- return (Initializer != NULL &&
- InnerMatcher.Matches(*Initializer, Finder, Builder));
-}
-
-/// Checks that a call expression or a constructor call expression has
-/// a specific number of arguments (including absent default arguments).
-///
-/// Example matches f(0, 0) (matcher = Call(ArgumentCountIs(2)))
-/// void f(int x, int y);
-/// f(0, 0);
-AST_POLYMORPHIC_MATCHER_P(ArgumentCountIs, unsigned, N) {
- COMPILE_ASSERT((llvm::is_base_of<clang::CallExpr, NodeType>::value ||
- llvm::is_base_of<clang::CXXConstructExpr, NodeType>::value),
- instantiated_with_wrong_types);
- return Node.getNumArgs() == N;
-}
-
-/// Matches the n'th argument of a call expression or a constructor
-/// call expression.
-///
-/// Example matches y in x(y)
-/// (matcher = Call(HasArgument(0, DeclarationReference())))
-/// void x(int) { int y; x(y); }
-AST_POLYMORPHIC_MATCHER_P2(
- HasArgument, unsigned, N, Matcher<clang::Expr>, InnerMatcher) {
- COMPILE_ASSERT((llvm::is_base_of<clang::CallExpr, NodeType>::value ||
- llvm::is_base_of<clang::CXXConstructExpr, NodeType>::value),
- instantiated_with_wrong_types);
- assert(N >= 0);
- return (N < Node.getNumArgs() &&
- InnerMatcher.Matches(
- *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
-}
-
-/// Matches any argument of a call expression or a constructor call expression.
-///
-/// Given
-/// void x(int, int, int) { int y; x(1, y, 42); }
-/// Call(HasAnyArgument(DeclarationReference()))
-/// matches x(1, y, 42)
-/// with HasAnyArgument(...)
-/// matching y
-AST_POLYMORPHIC_MATCHER_P(HasAnyArgument, Matcher<clang::Expr>, InnerMatcher) {
- COMPILE_ASSERT((llvm::is_base_of<clang::CallExpr, NodeType>::value ||
- llvm::is_base_of<clang::CXXConstructExpr, NodeType>::value),
- instantiated_with_wrong_types);
- for (unsigned I = 0; I < Node.getNumArgs(); ++I) {
- if (InnerMatcher.Matches(*Node.getArg(I)->IgnoreParenImpCasts(),
- Finder, Builder)) {
- return true;
- }
- }
- return false;
-}
-
-/// Matches the n'th parameter of a function declaration.
-///
-/// Given
-/// class X { void f(int x) {} };
-/// Method(HasParameter(0, HasType(Variable())))
-/// matches f(int x) {}
-/// with HasParameter(...)
-/// matching int x
-AST_MATCHER_P2(clang::FunctionDecl, HasParameter,
- unsigned, N, Matcher<clang::ParmVarDecl>, InnerMatcher) {
- return (N < Node.getNumParams() &&
- InnerMatcher.Matches(
- *Node.getParamDecl(N), Finder, Builder));
-}
-
-/// Matches any parameter of a function declaration.
-/// Does not match the 'this' parameter of a method.
-///
-/// Given
-/// class X { void f(int x, int y, int z) {} };
-/// Method(HasAnyParameter(HasName("y")))
-/// matches f(int x, int y, int z) {}
-/// with HasAnyParameter(...)
-/// matching int y
-AST_MATCHER_P(clang::FunctionDecl, HasAnyParameter,
- Matcher<clang::ParmVarDecl>, InnerMatcher) {
- for (unsigned I = 0; I < Node.getNumParams(); ++I) {
- if (InnerMatcher.Matches(*Node.getParamDecl(I), Finder, Builder)) {
- return true;
- }
- }
- return false;
-}
-
-/// Matches the condition expression of an if statement or conditional operator.
-///
-/// Example matches true (matcher = HasCondition(BoolLiteral(Equals(true))))
-/// if (true) {}
-AST_POLYMORPHIC_MATCHER_P(HasCondition, Matcher<clang::Expr>, InnerMatcher) {
- COMPILE_ASSERT((llvm::is_base_of<clang::IfStmt, NodeType>::value) ||
- (llvm::is_base_of<clang::ConditionalOperator,
- NodeType>::value),
- has_condition_requires_if_statement_or_conditional_operator);
- const clang::Expr *const Condition = Node.getCond();
- return (Condition != NULL &&
- InnerMatcher.Matches(*Condition, Finder, Builder));
-}
-
-/// Matches a 'for' statement that has a given body.
-///
-/// Given
-/// for (;;) {}
-/// HasBody(CompoundStatement())
-/// matches 'for (;;) {}'
-/// with CompoundStatement()
-/// matching '{}'
-AST_MATCHER_P(clang::ForStmt, HasBody, Matcher<clang::Stmt>, InnerMatcher) {
- const clang::Stmt *const Statement = Node.getBody();
- return (Statement != NULL &&
- InnerMatcher.Matches(*Statement, Finder, Builder));
-}
-
-/// Matches compound statements where at least one substatement matches a
-/// given matcher.
-///
-/// Given
-/// { {}; 1+2; }
-/// HasAnySubstatement(CompoundStatement())
-/// matches '{ {}; 1+2; }'
-/// with CompoundStatement()
-/// matching '{}'
-AST_MATCHER_P(clang::CompoundStmt, HasAnySubstatement,
- Matcher<clang::Stmt>, InnerMatcher) {
- for (clang::CompoundStmt::const_body_iterator It = Node.body_begin();
- It != Node.body_end();
- ++It) {
- if (InnerMatcher.Matches(**It, Finder, Builder)) return true;
- }
- return false;
-}
-
-/// Checks that a compound statement contains a specific number of child
-/// statements.
-///
-/// Example: Given
-/// { for (;;) {} }
-/// CompoundStatement(StatementCountIs(0)))
-/// matches '{}'
-/// but does not match the outer compound statement.
-AST_MATCHER_P(clang::CompoundStmt, StatementCountIs, unsigned, N) {
- return Node.size() == N;
-}
-
-/// Matches literals that are equal to the given value.
-///
-/// Example matches true (matcher = BoolLiteral(Equals(true)))
-/// true
-template <typename ValueT>
-PolymorphicMatcherWithParam1<ValueEqualsMatcher, ValueT> Equals(
- const ValueT &Value) {
- return PolymorphicMatcherWithParam1<ValueEqualsMatcher, ValueT>(Value);
-}
-
-/// Matches the operator Name of operator expressions (binary or unary).
-///
-/// Example matches a || b (matcher = BinaryOperator(HasOperatorName("||")))
-/// !(a || b)
-AST_POLYMORPHIC_MATCHER_P(HasOperatorName, std::string, Name) {
- COMPILE_ASSERT(
- (llvm::is_base_of<clang::BinaryOperator, NodeType>::value) ||
- (llvm::is_base_of<clang::UnaryOperator, NodeType>::value),
- has_condition_requires_if_statement_or_conditional_operator);
- return Name == Node.getOpcodeStr(Node.getOpcode());
-}
-
-/// Matches the left hand side of binary operator expressions.
-///
-/// Example matches a (matcher = BinaryOperator(HasLHS()))
-/// a || b
-AST_MATCHER_P(clang::BinaryOperator, HasLHS,
- Matcher<clang::Expr>, InnerMatcher) {
- clang::Expr *LeftHandSide = Node.getLHS();
- return (LeftHandSide != NULL &&
- InnerMatcher.Matches(*LeftHandSide, Finder, Builder));
-}
-
-/// Matches the right hand side of binary operator expressions.
-///
-/// Example matches b (matcher = BinaryOperator(HasRHS()))
-/// a || b
-AST_MATCHER_P(clang::BinaryOperator, HasRHS,
- Matcher<clang::Expr>, InnerMatcher) {
- clang::Expr *RightHandSide = Node.getRHS();
- return (RightHandSide != NULL &&
- InnerMatcher.Matches(*RightHandSide, Finder, Builder));
-}
-
-/// Matches if either the left hand side or the right hand side of a binary
-/// operator matches.
-inline Matcher<clang::BinaryOperator> HasEitherOperand(
- const Matcher<clang::Expr> &InnerMatcher) {
- return AnyOf(HasLHS(InnerMatcher), HasRHS(InnerMatcher));
-}
-
-/// Matches if the operand of a unary operator matches.
-///
-/// Example matches true (matcher = HasOperand(BoolLiteral(Equals(true))))
-/// !true
-AST_MATCHER_P(clang::UnaryOperator, HasUnaryOperand,
- Matcher<clang::Expr>, InnerMatcher) {
- clang::Expr *Operand = Node.getSubExpr();
- return (Operand != NULL &&
- InnerMatcher.Matches(*Operand, Finder, Builder));
-}
-
-/// Matches the true branch expression of a conditional operator.
-///
-/// Example matches a
-/// condition ? a : b
-AST_MATCHER_P(clang::ConditionalOperator, HasTrueExpression,
- Matcher<clang::Expr>, InnerMatcher) {
- clang::Expr *Expression = Node.getTrueExpr();
- return (Expression != NULL &&
- InnerMatcher.Matches(*Expression, Finder, Builder));
-}
-
-/// Matches the false branch expression of a conditional operator.
-///
-/// Example matches b
-/// condition ? a : b
-AST_MATCHER_P(clang::ConditionalOperator, HasFalseExpression,
- Matcher<clang::Expr>, InnerMatcher) {
- clang::Expr *Expression = Node.getFalseExpr();
- return (Expression != NULL &&
- InnerMatcher.Matches(*Expression, Finder, Builder));
-}
-
-/// Matches if a declaration has a body attached.
-///
-/// Example matches A, va, fa
-/// class A {};
-/// class B; // Doesn't match, as it has no body.
-/// int va;
-/// extern int vb; // Doesn't match, as it doesn't define the variable.
-/// void fa() {}
-/// void fb(); // Doesn't match, as it has no body.
-inline PolymorphicMatcherWithParam0<IsDefinitionMatcher> IsDefinition() {
- return PolymorphicMatcherWithParam0<IsDefinitionMatcher>();
-}
-
-/// Matches the class declaration that the given method declaration belongs to.
-/// TODO(qrczak): Generalize this for other kinds of declarations.
-/// FIXME: What other kind of declarations would we need to generalize
-/// this to?
-///
-/// Example matches A() in the last line
-/// (matcher = ConstructorCall(HasDeclaration(Method(
-/// OfClass(HasName("A"))))))
-/// class A {
-/// public:
-/// A();
-/// };
-/// A a = A();
-AST_MATCHER_P(clang::CXXMethodDecl, OfClass,
- Matcher<clang::CXXRecordDecl>, InnerMatcher) {
- const clang::CXXRecordDecl *Parent = Node.getParent();
- return (Parent != NULL &&
- InnerMatcher.Matches(*Parent, Finder, Builder));
-}
-
-/// Matches member expressions that are called with '->' as opposed to '.'.
-/// Member calls on the implicit this pointer match as called with '->'.
-///
-/// Given
-/// class Y {
-/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
-/// int a;
-/// static int b;
-/// };
-/// MemberExpression(IsArrow())
-/// matches this->x, x, y.x, a, this->b
-inline Matcher<clang::MemberExpr> IsArrow() {
- return MakeMatcher(new IsArrowMatcher());
-}
-
-} // namespace match
-
-/// Runs over an AST and finds matches.
-/// FIXME: Define exactly what "one match" is.
-///
-/// Not intended to be subclassed.
-class MatchFinder {
- public:
- struct MatchResult {
- BoundNodes Nodes;
-
- ///@{
- /// Utilities for interpreting the matched AST structures.
- clang::ASTContext *Context;
- clang::SourceManager *SourceManager;
- ///@}
- };
-
- /// Called when the Match registered for it was successfully found in the AST.
- class MatchCallback {
- public:
- virtual ~MatchCallback();
- virtual void Run(const MatchResult &Result) = 0;
- };
-
- /// Called when parsing is finished. Intended for testing only.
- class ParsingDoneTestCallback {
- public:
- virtual ~ParsingDoneTestCallback();
- virtual void Run() = 0;
- };
-
- MatchFinder();
- ~MatchFinder();
-
- /// Adds a NodeMatcher to match when running over the AST.
- /// Calls action with the BoundNodes on every match.
- /// Adding more than one InnerMatcher allows finding different matches in a
- /// single pass over the AST.
- void AddMatcher(const Matcher<clang::Decl> &NodeMatch,
- MatchCallback *Action);
- /// Adds a NodeMatcher to match when running over the AST.
- /// Calls action with the BoundNodes on every match.
- /// Adding more than one InnerMatcher allows finding different matches in a
- /// single pass over the AST.
- void AddMatcher(const Matcher<clang::QualType> &NodeMatch,
- MatchCallback *Action);
- /// Adds a NodeMatcher to match when running over the AST.
- /// Calls action with the BoundNodes on every match.
- /// Adding more than one InnerMatcher allows finding different matches in a
- /// single pass over the AST.
- void AddMatcher(const Matcher<clang::Stmt> &NodeMatch,
- MatchCallback *Action);
-
- /// Finds all matches in the given code and runs the corresponding triggers.
- /// Returns true if the code parsed correctly.
- bool FindAll(const std::string &Code);
-
- /// Creates a clang FrontendAction factory that finds all matches.
- FrontendActionFactory *NewFrontendActionFactory();
-
- /// The provided closure is called after parsing is done, before the AST is
- /// traversed. Useful for benchmarking.
- /// Each call to FindAll(...) will call the closure once.
- void RegisterTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone);
-
- private:
- clang::FrontendAction *NewVisitorAction();
-
- /// The MatchCallback*'s will be called every time the UntypedBaseMatcher
- /// matches on the AST.
- std::vector< std::pair<const UntypedBaseMatcher*, MatchCallback*> > Triggers;
-
- /// Called when parsing is done.
- ParsingDoneTestCallback *ParsingDone;
-
- friend class MatchFinderFrontendActionFactory;
-};
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif // LLVM_CLANG_TOOLING_AST_MATCHERS_H
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
deleted file mode 100644
index 63c8b6eb22..0000000000
--- a/include/clang/Tooling/Tooling.h
+++ /dev/null
@@ -1,142 +0,0 @@
-//===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements functions to run clang tools standalone instead
-// of running them as a plugin.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_TOOLING_H
-#define LLVM_CLANG_TOOLING_TOOLING_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <string>
-#include <vector>
-
-namespace clang {
-
-class FrontendAction;
-
-namespace tooling {
-
-/// \brief Runs (and deletes) the tool on 'Code' with the -fsynatx-only flag.
-///
-/// \param ToolAction The action to run over the code.
-/// \param Code C++ code.
-///
-/// \return - True if 'ToolAction' was successfully executed.
-bool RunSyntaxOnlyToolOnCode(
- clang::FrontendAction *ToolAction, llvm::StringRef Code);
-
-/// \brief Runs (and deletes) the tool with the given Clang flags.
-///
-/// \param ToolAction The action to run over the code.
-/// \param Argc The number of elements in Argv.
-/// \param Argv The command line arguments, including the path the binary
-/// was started with (Argv[0]).
-bool RunToolWithFlags(
- clang::FrontendAction *ToolAction, int Argc, char *Argv[]);
-
-/// \brief Converts a vector<string> into a vector<char*> suitable to pass
-/// to main-style functions taking (int Argc, char *Argv[]).
-std::vector<char*> CommandLineToArgv(const std::vector<std::string> *Command);
-
-/// \brief Specifies the working directory and command of a compilation.
-struct CompileCommand {
- /// \brief The working directory the command was executed from.
- std::string Directory;
-
- /// \brief The command line that was executed.
- std::vector<std::string> CommandLine;
-};
-
-/// \brief Looks up the compile command for 'FileName' in 'JsonDatabase'.
-///
-/// \param FileName The path to an input file for which we want the compile
-/// command line. If the 'JsonDatabase' was created by CMake, this must be
-/// an absolute path inside the CMake source directory which does not have
-/// symlinks resolved.
-///
-/// \param JsonDatabase A JSON formatted list of compile commands. This lookup
-/// command supports only a subset of the JSON standard as written by CMake.
-///
-/// \param ErrorMessage If non-empty, an error occurred and 'ErrorMessage' will
-/// be set to contain the error message. In this case CompileCommand will
-/// contain an empty directory and command line.
-///
-/// \see JsonCompileCommandLineDatabase
-CompileCommand FindCompileArgsInJsonDatabase(
- llvm::StringRef FileName, llvm::StringRef JsonDatabase,
- std::string &ErrorMessage);
-
-// Interface to generate clang::FrontendActions.
-class FrontendActionFactory {
- public:
- virtual ~FrontendActionFactory();
-
- // Returns a new clang::FrontendAction. The caller takes ownership of the
- // returned action.
- virtual clang::FrontendAction* New() = 0;
-};
-
-/// \brief Utility to run a FrontendAction over a set of files.
-///
-/// This class is written to be usable for command line utilities.
-class ClangTool {
- public:
- /// \brief Construct a clang tool from a command line.
- ///
- /// This will parse the command line parameters and print an error message
- /// and exit the program if the command line does not specify the required
- /// parameters.
- ///
- /// Usage:
- /// $ tool-name <cmake-output-dir> <file1> <file2> ...
- ///
- /// where <cmake-output-dir> is a CMake build directory in which a file named
- /// compile_commands.json exists (enable -DCMAKE_EXPORT_COMPILE_COMMANDS in
- /// CMake to get this output).
- ///
- /// <file1> ... specify the paths of files in the CMake source tree. This
- /// path is looked up in the compile command database. If the path of a file
- /// is absolute, it needs to point into CMake's source tree. If the path is
- /// relative, the current working directory needs to be in the CMake source
- /// tree and the file must be in a subdirectory of the current working
- /// directory. "./" prefixes in the relative files will be automatically
- /// removed, but the rest of a relative path must be a suffix of a path in
- /// the compile command line database.
- ///
- /// For example, to use a tool on all files in a subtree of the source
- /// tree, use:
- ///
- /// /path/in/subtree $ find . -name '*.cpp' |
- /// xargs tool-name /path/to/source
- ///
- /// \param argc The argc argument from main.
- /// \param argv The argv argument from main.
- ClangTool(int argc, char **argv);
-
- /// Runs a frontend action over all files specified in the command line.
- ///
- /// \param ActionFactory Factory generating the frontend actions. The function
- /// takes ownership of this parameter. A new action is generated for every
- /// processed translation unit.
- int Run(FrontendActionFactory *ActionFactory);
-
- private:
- std::vector<std::string> Files;
- llvm::OwningPtr<llvm::MemoryBuffer> JsonDatabase;
-};
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif // LLVM_CLANG_TOOLING_TOOLING_H
diff --git a/include/clang/Tooling/VariadicFunction.h b/include/clang/Tooling/VariadicFunction.h
deleted file mode 100644
index 6c19d90615..0000000000
--- a/include/clang/Tooling/VariadicFunction.h
+++ /dev/null
@@ -1,1398 +0,0 @@
-//===--- VariadicFunctions.h - Variadic Functions ---------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements compile-time type-safe variadic functions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_VARIADIC_FUNCTION_H
-#define LLVM_CLANG_TOOLING_VARIADIC_FUNCTION_H
-
-#include <stddef.h> // Defines NULL.
-
-namespace clang {
-namespace tooling {
-namespace internal {
-
-/// The VariadicFunction class template makes it easy to define
-/// type-safe variadic functions where all arguments have the same
-/// type.
-///
-/// Suppose we need a variadic function like this:
-///
-/// Result Foo(const Arg &a0, const Arg &a1, ..., const Arg &an);
-///
-/// Instead of many overloads of Foo(), we only need to define a helper
-/// function that takes an array of arguments:
-///
-/// Result FooImpl(const Arg *const args[], int count) {
-/// // 'count' is the number of values in the array; args[i] is a pointer
-/// // to the i-th argument passed to Foo(). Therefore, write *args[i]
-/// // to access the i-th argument.
-/// ...
-/// }
-///
-/// and then define Foo() like this:
-///
-/// const VariadicFunction<Result, Arg, FooImpl> Foo;
-///
-/// VariadicFunction takes care of defining the overloads of Foo().
-///
-/// Actually, Foo is a function object (i.e. functor) instead of a plain
-/// function. This object is stateless and its constructor/destructor
-/// does nothing, so it's safe to call Foo(...) at any time.
-///
-/// Sometimes we need a variadic function to have some fixed leading
-/// arguments whose types may be different from that of the optional
-/// arguments. For example:
-///
-/// bool FullMatch(const StringRef &s, const RE &regex,
-/// const Arg &a0, ..., const Arg &an);
-///
-/// VariadicFunctionN is for such cases, where N is the number of fixed
-/// arguments. It is like VariadicFunction, except that it takes N more
-/// template arguments for the types of the fixed arguments:
-///
-/// bool FullMatchImpl(const StringRef &s, const RE &regex,
-/// const Arg *const args[], int count) { ... }
-/// const VariadicFunction2<bool, const StringRef&,
-/// const RE&, Arg, FullMatchImpl>
-/// FullMatch;
-///
-/// Currently VariadicFunction and friends support up-to 3
-/// fixed leading arguments and up-to 32 optional arguments.
-template <typename Result, typename Arg,
- Result (*Func)(const Arg *const [], int count)>
-class VariadicFunction {
- public:
- VariadicFunction() {}
-
- Result operator()() const {
- return Func(NULL, 0);
- }
-
- Result operator()(const Arg &a0) const {
- const Arg *const args[] = { &a0 };
- return Func(args, 1);
- }
-
- Result operator()(const Arg &a0, const Arg &a1) const {
- const Arg *const args[] = { &a0, &a1 };
- return Func(args, 2);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2) const {
- const Arg *const args[] = { &a0, &a1, &a2 };
- return Func(args, 3);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3 };
- return Func(args, 4);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4 };
- return Func(args, 5);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5 };
- return Func(args, 6);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6 };
- return Func(args, 7);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7 };
- return Func(args, 8);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8 };
- return Func(args, 9);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9 };
- return Func(args, 10);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10 };
- return Func(args, 11);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11 };
- return Func(args, 12);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12 };
- return Func(args, 13);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13 };
- return Func(args, 14);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14 };
- return Func(args, 15);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15 };
- return Func(args, 16);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16 };
- return Func(args, 17);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17 };
- return Func(args, 18);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18 };
- return Func(args, 19);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19 };
- return Func(args, 20);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19,
- &a20 };
- return Func(args, 21);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21 };
- return Func(args, 22);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21, const Arg &a22) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22 };
- return Func(args, 23);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21, const Arg &a22, const Arg &a23) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23 };
- return Func(args, 24);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21, const Arg &a22, const Arg &a23,
- const Arg &a24) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24 };
- return Func(args, 25);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21, const Arg &a22, const Arg &a23,
- const Arg &a24, const Arg &a25) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25 };
- return Func(args, 26);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21, const Arg &a22, const Arg &a23,
- const Arg &a24, const Arg &a25, const Arg &a26) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26 };
- return Func(args, 27);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21, const Arg &a22, const Arg &a23,
- const Arg &a24, const Arg &a25, const Arg &a26, const Arg &a27) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27 };
- return Func(args, 28);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21, const Arg &a22, const Arg &a23,
- const Arg &a24, const Arg &a25, const Arg &a26, const Arg &a27,
- const Arg &a28) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28 };
- return Func(args, 29);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21, const Arg &a22, const Arg &a23,
- const Arg &a24, const Arg &a25, const Arg &a26, const Arg &a27,
- const Arg &a28, const Arg &a29) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29 };
- return Func(args, 30);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21, const Arg &a22, const Arg &a23,
- const Arg &a24, const Arg &a25, const Arg &a26, const Arg &a27,
- const Arg &a28, const Arg &a29, const Arg &a30) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29, &a30 };
- return Func(args, 31);
- }
-
- Result operator()(const Arg &a0, const Arg &a1, const Arg &a2, const Arg &a3,
- const Arg &a4, const Arg &a5, const Arg &a6, const Arg &a7,
- const Arg &a8, const Arg &a9, const Arg &a10, const Arg &a11,
- const Arg &a12, const Arg &a13, const Arg &a14, const Arg &a15,
- const Arg &a16, const Arg &a17, const Arg &a18, const Arg &a19,
- const Arg &a20, const Arg &a21, const Arg &a22, const Arg &a23,
- const Arg &a24, const Arg &a25, const Arg &a26, const Arg &a27,
- const Arg &a28, const Arg &a29, const Arg &a30, const Arg &a31) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29, &a30, &a31 };
- return Func(args, 32);
- }
-};
-
-template <typename Result, typename Param0, typename Arg,
- Result (*Func)(Param0, const Arg *const [], int count)>
-class VariadicFunction1 {
- public:
- VariadicFunction1() {}
-
- Result operator()(Param0 p0) const {
- return Func(p0, NULL, 0);
- }
-
- Result operator()(Param0 p0, const Arg &a0) const {
- const Arg *const args[] = { &a0 };
- return Func(p0, args, 1);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1) const {
- const Arg *const args[] = { &a0, &a1 };
- return Func(p0, args, 2);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1,
- const Arg &a2) const {
- const Arg *const args[] = { &a0, &a1, &a2 };
- return Func(p0, args, 3);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3 };
- return Func(p0, args, 4);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4 };
- return Func(p0, args, 5);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5 };
- return Func(p0, args, 6);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6 };
- return Func(p0, args, 7);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7 };
- return Func(p0, args, 8);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8 };
- return Func(p0, args, 9);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9 };
- return Func(p0, args, 10);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10 };
- return Func(p0, args, 11);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11 };
- return Func(p0, args, 12);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12 };
- return Func(p0, args, 13);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13 };
- return Func(p0, args, 14);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14 };
- return Func(p0, args, 15);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15 };
- return Func(p0, args, 16);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16 };
- return Func(p0, args, 17);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17 };
- return Func(p0, args, 18);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18 };
- return Func(p0, args, 19);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19 };
- return Func(p0, args, 20);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19,
- &a20 };
- return Func(p0, args, 21);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21 };
- return Func(p0, args, 22);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21, const Arg &a22) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22 };
- return Func(p0, args, 23);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21, const Arg &a22,
- const Arg &a23) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23 };
- return Func(p0, args, 24);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21, const Arg &a22,
- const Arg &a23, const Arg &a24) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24 };
- return Func(p0, args, 25);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21, const Arg &a22,
- const Arg &a23, const Arg &a24, const Arg &a25) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25 };
- return Func(p0, args, 26);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21, const Arg &a22,
- const Arg &a23, const Arg &a24, const Arg &a25, const Arg &a26) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26 };
- return Func(p0, args, 27);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21, const Arg &a22,
- const Arg &a23, const Arg &a24, const Arg &a25, const Arg &a26,
- const Arg &a27) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27 };
- return Func(p0, args, 28);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21, const Arg &a22,
- const Arg &a23, const Arg &a24, const Arg &a25, const Arg &a26,
- const Arg &a27, const Arg &a28) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28 };
- return Func(p0, args, 29);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21, const Arg &a22,
- const Arg &a23, const Arg &a24, const Arg &a25, const Arg &a26,
- const Arg &a27, const Arg &a28, const Arg &a29) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29 };
- return Func(p0, args, 30);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21, const Arg &a22,
- const Arg &a23, const Arg &a24, const Arg &a25, const Arg &a26,
- const Arg &a27, const Arg &a28, const Arg &a29, const Arg &a30) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29, &a30 };
- return Func(p0, args, 31);
- }
-
- Result operator()(Param0 p0, const Arg &a0, const Arg &a1, const Arg &a2,
- const Arg &a3, const Arg &a4, const Arg &a5, const Arg &a6,
- const Arg &a7, const Arg &a8, const Arg &a9, const Arg &a10,
- const Arg &a11, const Arg &a12, const Arg &a13, const Arg &a14,
- const Arg &a15, const Arg &a16, const Arg &a17, const Arg &a18,
- const Arg &a19, const Arg &a20, const Arg &a21, const Arg &a22,
- const Arg &a23, const Arg &a24, const Arg &a25, const Arg &a26,
- const Arg &a27, const Arg &a28, const Arg &a29, const Arg &a30,
- const Arg &a31) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29, &a30, &a31 };
- return Func(p0, args, 32);
- }
-};
-
-template <typename Result, typename Param0, typename Param1, typename Arg,
- Result (*Func)(Param0, Param1, const Arg *const [], int count)>
-class VariadicFunction2 {
- public:
- VariadicFunction2() {}
-
- Result operator()(Param0 p0, Param1 p1) const {
- return Func(p0, p1, NULL, 0);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0) const {
- const Arg *const args[] = { &a0 };
- return Func(p0, p1, args, 1);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1) const {
- const Arg *const args[] = { &a0, &a1 };
- return Func(p0, p1, args, 2);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2) const {
- const Arg *const args[] = { &a0, &a1, &a2 };
- return Func(p0, p1, args, 3);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3 };
- return Func(p0, p1, args, 4);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4 };
- return Func(p0, p1, args, 5);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5 };
- return Func(p0, p1, args, 6);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6 };
- return Func(p0, p1, args, 7);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7 };
- return Func(p0, p1, args, 8);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8 };
- return Func(p0, p1, args, 9);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9 };
- return Func(p0, p1, args, 10);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10 };
- return Func(p0, p1, args, 11);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11 };
- return Func(p0, p1, args, 12);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12 };
- return Func(p0, p1, args, 13);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13 };
- return Func(p0, p1, args, 14);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14 };
- return Func(p0, p1, args, 15);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15 };
- return Func(p0, p1, args, 16);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16 };
- return Func(p0, p1, args, 17);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17 };
- return Func(p0, p1, args, 18);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18 };
- return Func(p0, p1, args, 19);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19 };
- return Func(p0, p1, args, 20);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19,
- &a20 };
- return Func(p0, p1, args, 21);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21 };
- return Func(p0, p1, args, 22);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21,
- const Arg &a22) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22 };
- return Func(p0, p1, args, 23);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21,
- const Arg &a22, const Arg &a23) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23 };
- return Func(p0, p1, args, 24);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21,
- const Arg &a22, const Arg &a23, const Arg &a24) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24 };
- return Func(p0, p1, args, 25);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21,
- const Arg &a22, const Arg &a23, const Arg &a24, const Arg &a25) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25 };
- return Func(p0, p1, args, 26);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21,
- const Arg &a22, const Arg &a23, const Arg &a24, const Arg &a25,
- const Arg &a26) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26 };
- return Func(p0, p1, args, 27);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21,
- const Arg &a22, const Arg &a23, const Arg &a24, const Arg &a25,
- const Arg &a26, const Arg &a27) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27 };
- return Func(p0, p1, args, 28);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21,
- const Arg &a22, const Arg &a23, const Arg &a24, const Arg &a25,
- const Arg &a26, const Arg &a27, const Arg &a28) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28 };
- return Func(p0, p1, args, 29);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21,
- const Arg &a22, const Arg &a23, const Arg &a24, const Arg &a25,
- const Arg &a26, const Arg &a27, const Arg &a28, const Arg &a29) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29 };
- return Func(p0, p1, args, 30);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21,
- const Arg &a22, const Arg &a23, const Arg &a24, const Arg &a25,
- const Arg &a26, const Arg &a27, const Arg &a28, const Arg &a29,
- const Arg &a30) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29, &a30 };
- return Func(p0, p1, args, 31);
- }
-
- Result operator()(Param0 p0, Param1 p1, const Arg &a0, const Arg &a1,
- const Arg &a2, const Arg &a3, const Arg &a4, const Arg &a5,
- const Arg &a6, const Arg &a7, const Arg &a8, const Arg &a9,
- const Arg &a10, const Arg &a11, const Arg &a12, const Arg &a13,
- const Arg &a14, const Arg &a15, const Arg &a16, const Arg &a17,
- const Arg &a18, const Arg &a19, const Arg &a20, const Arg &a21,
- const Arg &a22, const Arg &a23, const Arg &a24, const Arg &a25,
- const Arg &a26, const Arg &a27, const Arg &a28, const Arg &a29,
- const Arg &a30, const Arg &a31) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29, &a30, &a31 };
- return Func(p0, p1, args, 32);
- }
-};
-
-template <typename Result, typename Param0, typename Param1, typename Param2,
- typename Arg,
- Result (*Func)(Param0, Param1, Param2, const Arg *const [],
- int count)>
-class VariadicFunction3 {
- public:
- VariadicFunction3() {}
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2) const {
- return Func(p0, p1, p2, NULL, 0);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0) const {
- const Arg *const args[] = { &a0 };
- return Func(p0, p1, p2, args, 1);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1) const {
- const Arg *const args[] = { &a0, &a1 };
- return Func(p0, p1, p2, args, 2);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2) const {
- const Arg *const args[] = { &a0, &a1, &a2 };
- return Func(p0, p1, p2, args, 3);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3 };
- return Func(p0, p1, p2, args, 4);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4 };
- return Func(p0, p1, p2, args, 5);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5 };
- return Func(p0, p1, p2, args, 6);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6 };
- return Func(p0, p1, p2, args, 7);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7 };
- return Func(p0, p1, p2, args, 8);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8 };
- return Func(p0, p1, p2, args, 9);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9 };
- return Func(p0, p1, p2, args, 10);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10 };
- return Func(p0, p1, p2, args, 11);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11 };
- return Func(p0, p1, p2, args, 12);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12 };
- return Func(p0, p1, p2, args, 13);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13 };
- return Func(p0, p1, p2, args, 14);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14 };
- return Func(p0, p1, p2, args, 15);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15 };
- return Func(p0, p1, p2, args, 16);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16 };
- return Func(p0, p1, p2, args, 17);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17 };
- return Func(p0, p1, p2, args, 18);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18 };
- return Func(p0, p1, p2, args, 19);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19 };
- return Func(p0, p1, p2, args, 20);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19,
- &a20 };
- return Func(p0, p1, p2, args, 21);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21 };
- return Func(p0, p1, p2, args, 22);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21, const Arg &a22) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22 };
- return Func(p0, p1, p2, args, 23);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21, const Arg &a22, const Arg &a23) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23 };
- return Func(p0, p1, p2, args, 24);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21, const Arg &a22, const Arg &a23, const Arg &a24) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24 };
- return Func(p0, p1, p2, args, 25);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21, const Arg &a22, const Arg &a23, const Arg &a24,
- const Arg &a25) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25 };
- return Func(p0, p1, p2, args, 26);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21, const Arg &a22, const Arg &a23, const Arg &a24,
- const Arg &a25, const Arg &a26) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26 };
- return Func(p0, p1, p2, args, 27);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21, const Arg &a22, const Arg &a23, const Arg &a24,
- const Arg &a25, const Arg &a26, const Arg &a27) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27 };
- return Func(p0, p1, p2, args, 28);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21, const Arg &a22, const Arg &a23, const Arg &a24,
- const Arg &a25, const Arg &a26, const Arg &a27, const Arg &a28) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28 };
- return Func(p0, p1, p2, args, 29);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21, const Arg &a22, const Arg &a23, const Arg &a24,
- const Arg &a25, const Arg &a26, const Arg &a27, const Arg &a28,
- const Arg &a29) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29 };
- return Func(p0, p1, p2, args, 30);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21, const Arg &a22, const Arg &a23, const Arg &a24,
- const Arg &a25, const Arg &a26, const Arg &a27, const Arg &a28,
- const Arg &a29, const Arg &a30) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29, &a30 };
- return Func(p0, p1, p2, args, 31);
- }
-
- Result operator()(Param0 p0, Param1 p1, Param2 p2, const Arg &a0,
- const Arg &a1, const Arg &a2, const Arg &a3, const Arg &a4,
- const Arg &a5, const Arg &a6, const Arg &a7, const Arg &a8,
- const Arg &a9, const Arg &a10, const Arg &a11, const Arg &a12,
- const Arg &a13, const Arg &a14, const Arg &a15, const Arg &a16,
- const Arg &a17, const Arg &a18, const Arg &a19, const Arg &a20,
- const Arg &a21, const Arg &a22, const Arg &a23, const Arg &a24,
- const Arg &a25, const Arg &a26, const Arg &a27, const Arg &a28,
- const Arg &a29, const Arg &a30, const Arg &a31) const {
- const Arg *const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
- &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
- &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29, &a30, &a31 };
- return Func(p0, p1, p2, args, 32);
- }
-};
-
-} // end namespace internal
-} // end namespace tooling
-} // end namespace clang
-
-#endif // LLVM_CLANG_TOOLING_VARIADIC_FUNCTION_H
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 0943e2b1c7..b4574344bc 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -13,4 +13,3 @@ add_subdirectory(Frontend)
add_subdirectory(FrontendTool)
add_subdirectory(Index)
add_subdirectory(StaticAnalyzer)
-add_subdirectory(Tooling)
diff --git a/lib/Makefile b/lib/Makefile
index eda7017bb8..924819c818 100755
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -10,7 +10,7 @@ CLANG_LEVEL := ..
PARALLEL_DIRS = Headers Basic Lex Parse AST Sema CodeGen Analysis \
StaticAnalyzer Rewrite Serialization Frontend FrontendTool \
- Index Driver Tooling
+ Index Driver
include $(CLANG_LEVEL)/Makefile
diff --git a/lib/Tooling/ASTMatchers.cpp b/lib/Tooling/ASTMatchers.cpp
deleted file mode 100644
index f03580ea34..0000000000
--- a/lib/Tooling/ASTMatchers.cpp
+++ /dev/null
@@ -1,564 +0,0 @@
-//===--- ASTMatchers.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.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a framework of AST matchers that can be used to express
-// structural queries on C++ code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/Tooling/ASTMatchers.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/DenseMap.h"
-#include <assert.h>
-#include <stddef.h>
-#include <set>
-#include <utility>
-
-namespace clang {
-namespace tooling {
-
-// Returns the value that 'a_map' maps 'key' to, or NULL if 'key' is
-// not in 'a_map'.
-template <typename Map>
-static const typename Map::mapped_type *Find(
- const Map &AMap, const typename Map::key_type &Key) {
- typename Map::const_iterator It = AMap.find(Key);
- return It == AMap.end() ? NULL : &It->second;
-}
-
-// We use memoization to avoid running the same matcher on the same
-// AST node twice. This pair is the key for looking up match
-// result. It consists of an ID of the MatcherInterface (for
-// identifying the matcher) and a pointer to the AST node.
-typedef std::pair<uint64_t, const void*> UntypedMatchInput;
-
-// Used to store the result of a match and possibly bound nodes.
-struct MemoizedMatchResult {
- bool ResultOfMatch;
- BoundNodes Nodes;
-};
-
-// A RecursiveASTVisitor that traverses all children or all descendants of
-// a node.
-class MatchChildASTVisitor
- : public clang::RecursiveASTVisitor<MatchChildASTVisitor> {
- public:
- typedef clang::RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase;
-
- // Creates an AST visitor that matches 'matcher' on all children or
- // descendants of a traversed node. max_depth is the maximum depth
- // to traverse: use 1 for matching the children and INT_MAX for
- // matching the descendants.
- MatchChildASTVisitor(const UntypedBaseMatcher *BaseMatcher,
- ASTMatchFinder *Finder,
- BoundNodesBuilder *Builder,
- int MaxDepth,
- ASTMatchFinder::TraversalMethod Traversal)
- : BaseMatcher(BaseMatcher),
- Finder(Finder),
- Builder(Builder),
- CurrentDepth(-1),
- MaxDepth(MaxDepth),
- Traversal(Traversal),
- Matches(false) {}
-
- // Returns true if a match is found in the subtree rooted at the
- // given AST node. This is done via a set of mutually recursive
- // functions. Here's how the recursion is done (the *wildcard can
- // actually be Decl, Stmt, or Type):
- //
- // - Traverse(node) calls BaseTraverse(node) when it needs
- // to visit the descendants of node.
- // - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node))
- // Traverse*(c) for each child c of 'node'.
- // - Traverse*(c) in turn calls Traverse(c), completing the
- // recursion.
- template <typename T>
- bool FindMatch(const T &Node) {
- Reset();
- Traverse(Node);
- return Matches;
- }
-
- // The following are overriding methods from the base visitor class.
- // They are public only to allow CRTP to work. They are *not *part
- // of the public API of this class.
- bool TraverseDecl(clang::Decl *DeclNode) {
- return (DeclNode == NULL) || Traverse(*DeclNode);
- }
- bool TraverseStmt(clang::Stmt *StmtNode) {
- const clang::Stmt *StmtToTraverse = StmtNode;
- if (Traversal ==
- ASTMatchFinder::kIgnoreImplicitCastsAndParentheses) {
- const clang::Expr *ExprNode = dyn_cast_or_null<clang::Expr>(StmtNode);
- if (ExprNode != NULL) {
- StmtToTraverse = ExprNode->IgnoreParenImpCasts();
- }
- }
- return (StmtToTraverse == NULL) || Traverse(*StmtToTraverse);
- }
- bool TraverseType(clang::QualType TypeNode) {
- return Traverse(TypeNode);
- }
-
- bool shouldVisitTemplateInstantiations() const { return true; }
-
- private:
- // Resets the state of this object.
- void Reset() {
- Matches = false;
- CurrentDepth = -1;
- }
-
- // Forwards the call to the corresponding Traverse*() method in the
- // base visitor class.
- bool BaseTraverse(const clang::Decl &DeclNode) {
- return VisitorBase::TraverseDecl(const_cast<clang::Decl*>(&DeclNode));
- }
- bool BaseTraverse(const clang::Stmt &StmtNode) {
- return VisitorBase::TraverseStmt(const_cast<clang::Stmt*>(&StmtNode));
- }
- bool BaseTraverse(clang::QualType TypeNode) {
- return VisitorBase::TraverseType(TypeNode);
- }
-
- // Traverses the subtree rooted at 'node'; returns true if the
- // traversal should continue after this function returns; also sets
- // matched_ to true if a match is found during the traversal.
- template <typename T>
- bool Traverse(const T &Node) {
- COMPILE_ASSERT(IsBaseType<T>::value,
- traverse_can_only_be_instantiated_with_base_type);
- ++CurrentDepth;
- bool ShouldContinue;
- if (CurrentDepth == 0) {
- // We don't want to match the root node, so just recurse.
- ShouldContinue = BaseTraverse(Node);
- } else if (BaseMatcher->Matches(Node, Finder, Builder)) {
- Matches = true;
- ShouldContinue = false; // Abort as soon as a match is found.
- } else if (CurrentDepth < MaxDepth) {
- // The current node doesn't match, and we haven't reached the
- // maximum depth yet, so recurse.
- ShouldContinue = BaseTraverse(Node);
- } else {
- // The current node doesn't match, and we have reached the
- // maximum depth, so don't recurse (but continue the traversal
- // such that other nodes at the current level can be visited).
- ShouldContinue = true;
- }
- --CurrentDepth;
- return ShouldContinue;
- }
-
- const UntypedBaseMatcher *const BaseMatcher;
- ASTMatchFinder *const Finder;
- BoundNodesBuilder *const Builder;
- int CurrentDepth;
- const int MaxDepth;
- const ASTMatchFinder::TraversalMethod Traversal;
- bool Matches;
-};
-
-// Controls the outermost traversal of the AST and allows to match multiple
-// matchers.
-class MatchASTVisitor : public clang::RecursiveASTVisitor<MatchASTVisitor>,
- public ASTMatchFinder {
- public:
- MatchASTVisitor(std::vector< std::pair<const UntypedBaseMatcher*,
- MatchFinder::MatchCallback*> > *Triggers,
- clang::SourceManager *VisitorSourceManager,
- clang::LangOptions *LanguageOptions)
- : Triggers(Triggers),
- VisitorSourceManager(VisitorSourceManager),
- LanguageOptions(LanguageOptions),
- ActiveASTContext(NULL) {
- assert(VisitorSourceManager != NULL);
- assert(LanguageOptions != NULL);
- // FIXME: add rewriter_(*source_manager, *language_options)
- }
-
- void set_active_ast_context(clang::ASTContext *NewActiveASTContext) {
- ActiveASTContext = NewActiveASTContext;
- }
-
- // The following Visit*() and Traverse*() functions "override"
- // methods in RecursiveASTVisitor.
-
- bool VisitTypedefDecl(clang::TypedefDecl *DeclNode) {
- // When we see 'typedef A B', we add name 'B' to the set of names
- // A's canonical type maps to. This is necessary for implementing
- // IsDerivedFrom(x) properly, where x can be the name of the base
- // class or any of its aliases.
- //
- // In general, the is-alias-of (as defined by typedefs) relation
- // is tree-shaped, as you can typedef a type more than once. For
- // example,
- //
- // typedef A B;
- // typedef A C;
- // typedef C D;
- // typedef C E;
- //
- // gives you
- //
- // A
- // |- B
- // `- C
- // |- D
- // `- E
- //
- // It is wrong to assume that the relation is a chain. A correct
- // implementation of IsDerivedFrom() needs to recognize that B and
- // E are aliases, even though neither is a typedef of the other.
- // Therefore, we cannot simply walk through one typedef chain to
- // find out whether the type name matches.
- const clang::Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr();
- const clang::Type *CanonicalType = // root of the typedef tree
- ActiveASTContext->getCanonicalType(TypeNode);
- TypeToUnqualifiedAliases[CanonicalType].insert(
- DeclNode->getName().str());
- return true;
- }
-
- bool TraverseDecl(clang::Decl *DeclNode);
- bool TraverseStmt(clang::Stmt *StmtNode);
- bool TraverseType(clang::QualType TypeNode);
- bool TraverseTypeLoc(clang::TypeLoc TypeNode);
-
- // Matches children or descendants of 'Node' with 'BaseMatcher'.
- template <typename T>
- bool MemoizedMatchesRecursively(
- const T &Node, const UntypedBaseMatcher &BaseMatcher,
- BoundNodesBuilder *Builder, int MaxDepth,
- TraversalMethod Traversal) {
- COMPILE_ASSERT((llvm::is_same<T, clang::Decl>::value) ||
- (llvm::is_same<T, clang::Stmt>::value),
- type_does_not_support_memoization);
- const UntypedMatchInput input(BaseMatcher.GetID(), &Node);
- std::pair <MemoizationMap::iterator, bool>
- InsertResult = ResultCache.insert(
- std::make_pair(input, MemoizedMatchResult()));
- if (InsertResult.second) {
- BoundNodesBuilder DescendantBoundNodesBuilder;
- InsertResult.first->second.ResultOfMatch =
- MatchesRecursively(Node, BaseMatcher, &DescendantBoundNodesBuilder,
- MaxDepth, Traversal);
- InsertResult.first->second.Nodes =
- DescendantBoundNodesBuilder.Build();
- }
- InsertResult.first->second.Nodes.CopyTo(Builder);
- return InsertResult.first->second.ResultOfMatch;
- }
-
- // Matches children or descendants of 'Node' with 'BaseMatcher'.
- template <typename T>
- bool MatchesRecursively(
- const T &Node, const UntypedBaseMatcher &BaseMatcher,
- BoundNodesBuilder *Builder, int MaxDepth,
- TraversalMethod Traversal) {
- MatchChildASTVisitor Visitor(
- &BaseMatcher, this, Builder, MaxDepth, Traversal);
- return Visitor.FindMatch(Node);
- }
-
- virtual bool ClassIsDerivedFrom(const clang::CXXRecordDecl *Declaration,
- const std::string &BaseName) const;
-
- // Implements ASTMatchFinder::MatchesChildOf.
- virtual bool MatchesChildOf(const clang::Decl &DeclNode,
- const UntypedBaseMatcher &BaseMatcher,
- BoundNodesBuilder *Builder,
- TraversalMethod Traversal) {
- return MatchesRecursively(
- DeclNode, BaseMatcher, Builder, 1, Traversal);
- }
- virtual bool MatchesChildOf(const clang::Stmt &StmtNode,
- const UntypedBaseMatcher &BaseMatcher,
- BoundNodesBuilder *Builder,
- TraversalMethod Traversal) {
- return MatchesRecursively(
- StmtNode, BaseMatcher, Builder, 1, Traversal);
- }
-
- // Implements ASTMatchFinder::MatchesDescendantOf.
- virtual bool MatchesDescendantOf(const clang::Decl &DeclNode,
- const UntypedBaseMatcher &BaseMatcher,
- BoundNodesBuilder *Builder) {
- return MemoizedMatchesRecursively(
- DeclNode, BaseMatcher, Builder, INT_MAX, kAsIs);
- }
- virtual bool MatchesDescendantOf(const clang::Stmt &StmtNode,
- const UntypedBaseMatcher &BaseMatcher,
- BoundNodesBuilder *Builder) {
- return MemoizedMatchesRecursively(
- StmtNode, BaseMatcher, Builder, INT_MAX, kAsIs);
- }
-
- bool shouldVisitTemplateInstantiations() const { return true; }
-
- private:
- // Returns true if 'TypeNode' is also known by the name 'Name'. In other
- // words, there is a type (including typedef) with the name 'Name'
- // that is equal to 'TypeNode'.
- bool TypeHasAlias(
- const clang::Type *TypeNode, const std::string &Name) const {
- const clang::Type *const CanonicalType =
- ActiveASTContext->getCanonicalType(TypeNode);
- const std::set<std::string> *UnqualifiedAlias =
- Find(TypeToUnqualifiedAliases, CanonicalType);
- return UnqualifiedAlias != NULL && UnqualifiedAlias->count(Name) > 0;
- }
-
- // Matches all registered matchers on the given node and calls the
- // result callback for every node that matches.
- template <typename T>
- void Match(const T &node) {
- for (std::vector< std::pair<const UntypedBaseMatcher*,
- MatchFinder::MatchCallback*> >::const_iterator
- It = Triggers->begin(), End = Triggers->end();
- It != End; ++It) {
- BoundNodesBuilder Builder;
- if (It->first->Matches(node, this, &Builder)) {
- MatchFinder::MatchResult Result;
- Result.Nodes = Builder.Build();
- Result.Context = ActiveASTContext;
- Result.SourceManager = VisitorSourceManager;
- It->second->Run(Result);
- }
- }
- }
-
- std::vector< std::pair<const UntypedBaseMatcher*,
- MatchFinder::MatchCallback*> > *const Triggers;
- clang::SourceManager *const VisitorSourceManager;
- clang::LangOptions *const LanguageOptions;
- clang::ASTContext *ActiveASTContext;
-
- // Maps a canonical type to the names of its typedefs.
- llvm::DenseMap<const clang::Type*, std::set<std::string> >
- TypeToUnqualifiedAliases;
-
- // Maps (matcher, node) -> the match result for memoization.
- typedef llvm::DenseMap<UntypedMatchInput, MemoizedMatchResult> MemoizationMap;
- MemoizationMap ResultCache;
-};
-
-// Returns true if the given class is directly or indirectly derived
-// from a base type with the given name. A class is considered to be
-// also derived from itself.
-bool MatchASTVisitor::ClassIsDerivedFrom(
- const clang::CXXRecordDecl *Declaration,
- const std::string &BaseName) const {
- if (std::string(Declaration->getName()) == BaseName) {
- return true;
- }
- if (!Declaration->hasDefinition()) {
- return false;
- }
- typedef clang::CXXRecordDecl::base_class_const_iterator BaseIterator;
- for (BaseIterator It = Declaration->bases_begin(),
- End = Declaration->bases_end(); It != End; ++It) {
- const clang::Type *TypeNode = It->getType().getTypePtr();
-
- if (TypeHasAlias(TypeNode, BaseName))
- return true;
-
- // clang::Type::getAs<...>() drills through typedefs.
- if (TypeNode->getAs<clang::DependentNameType>() != NULL ||
- TypeNode->getAs<clang::TemplateTypeParmType>() != NULL) {
- // Dependent names and template TypeNode parameters will be matched when
- // the template is instantiated.
- continue;
- }
- clang::CXXRecordDecl *ClassDecl = NULL;
- clang::TemplateSpecializationType const *TemplateType =
- TypeNode->getAs<clang::TemplateSpecializationType>();
- if (TemplateType != NULL) {
- if (TemplateType->getTemplateName().isDependent()) {
- // Dependent template specializations will be matched when the
- // template is instantiated.
- continue;
- }
- // For template specialization types which are specializing a template
- // declaration which is an explicit or partial specialization of another
- // template declaration, getAsCXXRecordDecl() returns the corresponding
- // ClassTemplateSpecializationDecl.
- //
- // For template specialization types which are specializing a template
- // declaration which is neither an explicit nor partial specialization of
- // another template declaration, getAsCXXRecordDecl() returns NULL and
- // we get the CXXRecordDecl of the templated declaration.
- clang::CXXRecordDecl *SpecializationDecl =
- TemplateType->getAsCXXRecordDecl();
- if (SpecializationDecl != NULL) {
- ClassDecl = SpecializationDecl;
- } else {
- ClassDecl = llvm::dyn_cast<clang::CXXRecordDecl>(
- TemplateType->getTemplateName()
- .getAsTemplateDecl()->getTemplatedDecl());
- }
- } else {
- ClassDecl = TypeNode->getAsCXXRecordDecl();
- }
- assert(ClassDecl != NULL);
- assert(ClassDecl != Declaration);
- if (ClassIsDerivedFrom(ClassDecl, BaseName)) {
- return true;
- }
- }
- return false;
-}
-
-bool MatchASTVisitor::TraverseDecl(clang::Decl *DeclNode) {
- if (DeclNode == NULL) {
- return true;
- }
- Match(*DeclNode);
- return clang::RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode);
-}
-
-bool MatchASTVisitor::TraverseStmt(clang::Stmt *StmtNode) {
- if (StmtNode == NULL) {
- return true;
- }
- Match(*StmtNode);
- return clang::RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode);
-}
-
-bool MatchASTVisitor::TraverseType(clang::QualType TypeNode) {
- Match(TypeNode);
- return clang::RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode);
-}
-
-bool MatchASTVisitor::TraverseTypeLoc(clang::TypeLoc TypeLoc) {
- return clang::RecursiveASTVisitor<MatchASTVisitor>::
- TraverseType(TypeLoc.getType());
-}
-
-class MatchASTConsumer : public clang::ASTConsumer {
- public:
- MatchASTConsumer(std::vector< std::pair<const UntypedBaseMatcher*,
- MatchFinder::MatchCallback*> > *Triggers,
- MatchFinder::ParsingDoneTestCallback *ParsingDone,
- clang::SourceManager *ConsumerSourceManager,
- clang::LangOptions *LanaguageOptions)
- : Visitor(Triggers, ConsumerSourceManager, LanaguageOptions),
- ParsingDone(ParsingDone) {}
-
- private:
- virtual void HandleTranslationUnit(
- clang::ASTContext &Context) { // NOLINT: external API uses refs
- if (ParsingDone != NULL) {
- ParsingDone->Run();
- }
- Visitor.set_active_ast_context(&Context);
- Visitor.TraverseDecl(Context.getTranslationUnitDecl());
- Visitor.set_active_ast_context(NULL);
- }
-
- MatchASTVisitor Visitor;
- MatchFinder::ParsingDoneTestCallback *ParsingDone;
-};
-
-class MatchASTAction : public clang::ASTFrontendAction {
- public:
- explicit MatchASTAction(
- std::vector< std::pair<const UntypedBaseMatcher*,
- MatchFinder::MatchCallback*> > *Triggers,
- MatchFinder::ParsingDoneTestCallback *ParsingDone)
- : Triggers(Triggers),
- ParsingDone(ParsingDone) {}
-
- private:
- clang::ASTConsumer *CreateASTConsumer(
- clang::CompilerInstance &Compiler,
- llvm::StringRef) {
- return new MatchASTConsumer(Triggers,
- ParsingDone,
- &Compiler.getSourceManager(),
- &Compiler.getLangOpts());
- }
-
- std::vector< std::pair<const UntypedBaseMatcher*,
- MatchFinder::MatchCallback*> > *const Triggers;
- MatchFinder::ParsingDoneTestCallback *ParsingDone;
-};
-
-MatchFinder::MatchCallback::~MatchCallback() {}
-MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {}
-
-MatchFinder::MatchFinder() : ParsingDone(NULL) {}
-
-MatchFinder::~MatchFinder() {
- for (std::vector< std::pair<const UntypedBaseMatcher*,
- MatchFinder::MatchCallback*> >::const_iterator
- It = Triggers.begin(), End = Triggers.end();
- It != End; ++It) {
- delete It->first;
- delete It->second;
- }
-}
-
-void MatchFinder::AddMatcher(const Matcher<clang::Decl> &NodeMatch,
- MatchCallback *Action) {
- Triggers.push_back(std::make_pair(
- new TypedBaseMatcher<clang::Decl>(NodeMatch), Action));
-}
-
-void MatchFinder::AddMatcher(const Matcher<clang::QualType> &NodeMatch,
- MatchCallback *Action) {
- Triggers.push_back(std::make_pair(
- new TypedBaseMatcher<clang::QualType>(NodeMatch), Action));
-}
-
-void MatchFinder::AddMatcher(const Matcher<clang::Stmt> &NodeMatch,
- MatchCallback *Action) {
- Triggers.push_back(std::make_pair(
- new TypedBaseMatcher<clang::Stmt>(NodeMatch), Action));
-}
-
-bool MatchFinder::FindAll(const std::string &Code) {
- return RunSyntaxOnlyToolOnCode(
- new MatchASTAction(&Triggers, ParsingDone), Code);
-}
-
-clang::FrontendAction *MatchFinder::NewVisitorAction() {
- return new MatchASTAction(&Triggers, ParsingDone);
-}
-
-class MatchFinderFrontendActionFactory : public FrontendActionFactory {
- public:
- explicit MatchFinderFrontendActionFactory(MatchFinder *Finder)
- : Finder(Finder) {}
-
- virtual clang::FrontendAction *New() {
- return Finder->NewVisitorAction();
- }
-
- private:
- MatchFinder *const Finder;
-};
-
-FrontendActionFactory *MatchFinder::NewFrontendActionFactory() {
- return new MatchFinderFrontendActionFactory(this);
-}
-
-void MatchFinder::RegisterTestCallbackAfterParsing(
- MatchFinder::ParsingDoneTestCallback *NewParsingDone) {
- ParsingDone = NewParsingDone;
-}
-
-} // end namespace tooling
-} // end namespace clang
diff --git a/lib/Tooling/CMakeLists.txt b/lib/Tooling/CMakeLists.txt
deleted file mode 100644
index 0a0020a555..0000000000
--- a/lib/Tooling/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-SET(LLVM_USED_LIBS clangBasic clangFrontend clangAST)
-
-add_clang_library(clangTooling
- ASTMatchers.cpp
- JsonCompileCommandLineDatabase.cpp
- Tooling.cpp
- )
diff --git a/lib/Tooling/JsonCompileCommandLineDatabase.cpp b/lib/Tooling/JsonCompileCommandLineDatabase.cpp
deleted file mode 100644
index 7f027cfbea..0000000000
--- a/lib/Tooling/JsonCompileCommandLineDatabase.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-//===--- JsonCompileCommandLineDatabase.cpp - Simple JSON database --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements reading a compile command line database, as written
-// out for example by CMake.
-//
-//===----------------------------------------------------------------------===//
-
-#include "JsonCompileCommandLineDatabase.h"
-#include "llvm/ADT/Twine.h"
-
-namespace clang {
-namespace tooling {
-
-namespace {
-
-// A parser for JSON escaped strings of command line arguments with \-escaping
-// for quoted arguments (see the documentation of UnescapeJsonCommandLine(...)).
-class CommandLineArgumentParser {
- public:
- CommandLineArgumentParser(llvm::StringRef CommandLine)
- : Input(CommandLine), Position(Input.begin()-1) {}
-
- std::vector<std::string> Parse() {
- bool HasMoreInput = true;
- while (HasMoreInput && NextNonWhitespace()) {
- std::string Argument;
- HasMoreInput = ParseStringInto(Argument);
- CommandLine.push_back(Argument);
- }
- return CommandLine;
- }
-
- private:
- // All private methods return true if there is more input available.
-
- bool ParseStringInto(std::string &String) {
- do {
- if (*Position == '"') {
- if (!ParseQuotedStringInto(String)) return false;
- } else {
- if (!ParseFreeStringInto(String)) return false;
- }
- } while (*Position != ' ');
- return true;
- }
-
- bool ParseQuotedStringInto(std::string &String) {
- if (!Next()) return false;
- while (*Position != '"') {
- if (!SkipEscapeCharacter()) return false;
- String.push_back(*Position);
- if (!Next()) return false;
- }
- return Next();
- }
-
- bool ParseFreeStringInto(std::string &String) {
- do {
- if (!SkipEscapeCharacter()) return false;
- String.push_back(*Position);
- if (!Next()) return false;
- } while (*Position != ' ' && *Position != '"');
- return true;
- }
-
- bool SkipEscapeCharacter() {
- if (*Position == '\\') {
- return Next();
- }
- return true;
- }
-
- bool NextNonWhitespace() {
- do {
- if (!Next()) return false;
- } while (*Position == ' ');
- return true;
- }
-
- bool Next() {
- ++Position;
- if (Position == Input.end()) return false;
- // Remove the JSON escaping first. This is done unconditionally.
- if (*Position == '\\') ++Position;
- return Position != Input.end();
- }
-
- const llvm::StringRef Input;
- llvm::StringRef::iterator Position;
- std::vector<std::string> CommandLine;
-};
-
-} // end namespace
-
-std::vector<std::string> UnescapeJsonCommandLine(
- llvm::StringRef JsonEscapedCommandLine) {
- CommandLineArgumentParser parser(JsonEscapedCommandLine);
- return parser.Parse();
-}
-
-JsonCompileCommandLineParser::JsonCompileCommandLineParser(
- const llvm::StringRef Input, CompileCommandHandler *CommandHandler)
- : Input(Input), Position(Input.begin()-1), CommandHandler(CommandHandler) {}
-
-bool JsonCompileCommandLineParser::Parse() {
- NextNonWhitespace();
- return ParseTranslationUnits();
-}
-
-std::string JsonCompileCommandLineParser::GetErrorMessage() const {
- return ErrorMessage;
-}
-
-bool JsonCompileCommandLineParser::ParseTranslationUnits() {
- if (!ConsumeOrError('[', "at start of compile command file")) return false;
- if (!ParseTranslationUnit(/*First=*/true)) return false;
- while (Consume(',')) {
- if (!ParseTranslationUnit(/*First=*/false)) return false;
- }
- if (!ConsumeOrError(']', "at end of array")) return false;
- if (CommandHandler != NULL) {
- CommandHandler->EndTranslationUnits();
- }
- return true;
-}
-
-bool JsonCompileCommandLineParser::ParseTranslationUnit(bool First) {
- if (First) {
- if (!Consume('{')) return true;
- } else {
- if (!ConsumeOrError('{', "at start of object")) return false;
- }
- if (!Consume('}')) {
- if (!ParseObjectKeyValuePairs()) return false;
- if (!ConsumeOrError('}', "at end of object")) return false;
- }
- if (CommandHandler != NULL) {
- CommandHandler->EndTranslationUnit();
- }
- return true;
-}
-
-bool JsonCompileCommandLineParser::ParseObjectKeyValuePairs() {
- do {
- llvm::StringRef Key;
- if (!ParseString(Key)) return false;
- if (!ConsumeOrError(':', "between name and value")) return false;
- llvm::StringRef Value;
- if (!ParseString(Value)) return false;
- if (CommandHandler != NULL) {
- CommandHandler->HandleKeyValue(Key, Value);
- }
- } while (Consume(','));
- return true;
-}
-
-bool JsonCompileCommandLineParser::ParseString(llvm::StringRef &String) {
- if (!ConsumeOrError('"', "at start of string")) return false;
- llvm::StringRef::iterator First = Position;
- llvm::StringRef::iterator Last = Position;
- while (!Consume('"')) {
- Consume('\\');
- ++Position;
- // We need to store Position, as Consume will change Last before leaving
- // the loop.
- Last = Position;
- }
- String = llvm::StringRef(First, Last - First);
- return true;
-}
-
-bool JsonCompileCommandLineParser::Consume(char C) {
- if (Position == Input.end()) return false;
- if (*Position != C) return false;
- NextNonWhitespace();
- return true;
-}
-
-bool JsonCompileCommandLineParser::ConsumeOrError(
- char C, llvm::StringRef Message) {
- if (!Consume(C)) {
- SetExpectError(C, Message);
- return false;
- }
- return true;
-}
-
-void JsonCompileCommandLineParser::SetExpectError(
- char C, llvm::StringRef Message) {
- ErrorMessage = (llvm::Twine("'") + llvm::StringRef(&C, 1) +
- "' expected " + Message + ".").str();
-}
-
-void JsonCompileCommandLineParser::NextNonWhitespace() {
- do {
- ++Position;
- } while (IsWhitespace());
-}
-
-bool JsonCompileCommandLineParser::IsWhitespace() {
- if (Position == Input.end()) return false;
- return (*Position == ' ' || *Position == '\t' ||
- *Position == '\n' || *Position == '\r');
-}
-
-} // end namespace tooling
-} // end namespace clang
diff --git a/lib/Tooling/JsonCompileCommandLineDatabase.h b/lib/Tooling/JsonCompileCommandLineDatabase.h
deleted file mode 100644
index ea7cf0e6e1..0000000000
--- a/lib/Tooling/JsonCompileCommandLineDatabase.h
+++ /dev/null
@@ -1,107 +0,0 @@
-//===--- JsonCompileCommandLineDatabase - Simple JSON database --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements reading a compile command line database, as written
-// out for example by CMake. It only supports the subset of the JSON standard
-// that is needed to parse the CMake output.
-// See http://www.json.org/ for the full standard.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_JSON_COMPILE_COMMAND_LINE_DATABASE_H
-#define LLVM_CLANG_TOOLING_JSON_COMPILE_COMMAND_LINE_DATABASE_H
-
-#include "llvm/ADT/StringRef.h"
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace tooling {
-
-/// \brief Converts a JSON escaped command line to a vector of arguments.
-///
-/// \param JsonEscapedCommandLine The escaped command line as a string. This
-/// is assumed to be escaped as a JSON string (e.g. " and \ are escaped).
-/// In addition, any arguments containing spaces are assumed to be \-escaped
-///
-/// For example, the input (|| denoting non C-escaped strings):
-/// |./call a \"b \\\" c \\\\ \" d|
-/// would yield:
-/// [ |./call|, |a|, |b " c \ |, |d| ].
-std::vector<std::string> UnescapeJsonCommandLine(
- llvm::StringRef JsonEscapedCommandLine);
-
-/// \brief Interface for users of the JsonCompileCommandLineParser.
-class CompileCommandHandler {
- public:
- virtual ~CompileCommandHandler() {}
-
- /// \brief Called after all translation units are parsed.
- virtual void EndTranslationUnits() {}
-
- /// \brief Called at the end of a single translation unit.
- virtual void EndTranslationUnit() {}
-
- /// \brief Called for every (Key, Value) pair in a translation unit
- /// description.
- virtual void HandleKeyValue(llvm::StringRef Key, llvm::StringRef Value) {}
-};
-
-/// \brief A JSON parser that supports the subset of JSON needed to parse
-/// JSON compile command line databases as written out by CMake.
-///
-/// The supported subset describes a list of compile command lines for
-/// each processed translation unit. The translation units are stored in a
-/// JSON array, where each translation unit is described by a JSON object
-/// containing (Key, Value) pairs for the working directory the compile command
-/// line was executed from, the main C/C++ input file of the translation unit
-/// and the actual compile command line, for example:
-/// [
-/// {
-/// "file":"/file.cpp",
-/// "directory":"/",
-/// "command":"/cc /file.cpp"
-/// }
-/// ]
-class JsonCompileCommandLineParser {
- public:
- /// \brief Create a parser on 'Input', calling 'CommandHandler' to handle the
- /// parsed constructs. 'CommandHandler' may be NULL in order to just check
- /// the validity of 'Input'.
- JsonCompileCommandLineParser(const llvm::StringRef Input,
- CompileCommandHandler *CommandHandler);
-
- /// \brief Parses the specified input. Returns true if no parsing errors were
- /// found.
- bool Parse();
-
- /// \brief Returns an error message if Parse() returned false previously.
- std::string GetErrorMessage() const;
-
- private:
- bool ParseTranslationUnits();
- bool ParseTranslationUnit(bool First);
- bool ParseObjectKeyValuePairs();
- bool ParseString(llvm::StringRef &String);
- bool Consume(char C);
- bool ConsumeOrError(char C, llvm::StringRef Message);
- void NextNonWhitespace();
- bool IsWhitespace();
- void SetExpectError(char C, llvm::StringRef Message);
-
- const llvm::StringRef Input;
- llvm::StringRef::iterator Position;
- std::string ErrorMessage;
- CompileCommandHandler * const CommandHandler;
-};
-
-} // end namespace tooling
-} // end namespace clang
-
-#endif // LLVM_CLANG_TOOLING_JSON_COMPILE_COMMAND_LINE_DATABASE_H
diff --git a/lib/Tooling/Makefile b/lib/Tooling/Makefile
deleted file mode 100644
index 501a00c3f4..0000000000
--- a/lib/Tooling/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- clang/lib/Tooling/Makefile ---------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-CLANG_LEVEL := ../..
-LIBRARYNAME := clangTooling
-
-include $(CLANG_LEVEL)/Makefile
-
-
diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp
deleted file mode 100644
index 97a9463852..0000000000
--- a/lib/Tooling/Tooling.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-//===--- Tooling.cpp - Running clang standalone tools ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements functions to run clang tools standalone instead
-// of running them as a plugin.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
-#include "clang/Basic/DiagnosticIDs.h"
-#include "clang/Driver/Compilation.h"
-#include "clang/Driver/Driver.h"
-#include "clang/Driver/Tool.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "JsonCompileCommandLineDatabase.h"
-#include <map>
-#include <cstdio>
-
-namespace clang {
-namespace tooling {
-
-namespace {
-
-// Checks that the input conforms to the argv[] convention as in
-// main(). Namely:
-// - it must contain at least a program path,
-// - argv[0], ..., and argv[argc - 1] mustn't be NULL, and
-// - argv[argc] must be NULL.
-void ValidateArgv(int argc, char *argv[]) {
- if (argc < 1) {
- fprintf(stderr, "ERROR: argc is %d. It must be >= 1.\n", argc);
- abort();
- }
-
- for (int i = 0; i < argc; ++i) {
- if (argv[i] == NULL) {
- fprintf(stderr, "ERROR: argv[%d] is NULL.\n", i);
- abort();
- }
- }
-
- if (argv[argc] != NULL) {
- fprintf(stderr, "ERROR: argv[argc] isn't NULL.\n");
- abort();
- }
-}
-
-} // end namespace
-
-// FIXME: This file contains structural duplication with other parts of the
-// code that sets up a compiler to run tools on it, and we should refactor
-// it to be based on the same framework.
-
-static clang::Diagnostic *NewTextDiagnostics() {
- llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(
- new clang::DiagnosticIDs());
- clang::TextDiagnosticPrinter *DiagClient = new clang::TextDiagnosticPrinter(
- llvm::errs(), clang::DiagnosticOptions());
- return new clang::Diagnostic(DiagIDs, DiagClient);
-}
-
-// Exists solely for the purpose of lookup of the main executable.
-static int StaticSymbol;
-
-/// \brief Builds a clang driver initialized for running clang tools.
-static clang::driver::Driver *NewDriver(clang::Diagnostic *Diagnostics,
- const char *BinaryName) {
- // This just needs to be some symbol in the binary.
- void *const SymbolAddr = &StaticSymbol;
- const llvm::sys::Path ExePath =
- llvm::sys::Path::GetMainExecutable(BinaryName, SymbolAddr);
-
- const std::string DefaultOutputName = "a.out";
- clang::driver::Driver *CompilerDriver = new clang::driver::Driver(
- ExePath.str(), llvm::sys::getHostTriple(),
- DefaultOutputName, false, false, *Diagnostics);
- CompilerDriver->setTitle("clang_based_tool");
- return CompilerDriver;
-}
-
-/// \brief Retrieves the clang CC1 specific flags out of the compilation's jobs.
-/// Returns NULL on error.
-static const clang::driver::ArgStringList *GetCC1Arguments(
- clang::Diagnostic *Diagnostics, clang::driver::Compilation *Compilation) {
- // We expect to get back exactly one Command job, if we didn't something
- // failed. Extract that job from the Compilation.
- const clang::driver::JobList &Jobs = Compilation->getJobs();
- if (Jobs.size() != 1 || !isa<clang::driver::Command>(*Jobs.begin())) {
- llvm::SmallString<256> error_msg;
- llvm::raw_svector_ostream error_stream(error_msg);
- Compilation->PrintJob(error_stream, Compilation->getJobs(), "; ", true);
- Diagnostics->Report(clang::diag::err_fe_expected_compiler_job)
- << error_stream.str();
- return NULL;
- }
-
- // The one job we find should be to invoke clang again.
- const clang::driver::Command *Cmd =
- cast<clang::driver::Command>(*Jobs.begin());
- if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
- Diagnostics->Report(clang::diag::err_fe_expected_clang_command);
- return NULL;
- }
-
- return &Cmd->getArguments();
-}
-
-/// \brief Returns a clang build invocation initialized from the CC1 flags.
-static clang::CompilerInvocation *NewInvocation(
- clang::Diagnostic *Diagnostics,
- const clang::driver::ArgStringList &CC1Args) {
- clang::CompilerInvocation *Invocation = new clang::CompilerInvocation;
- clang::CompilerInvocation::CreateFromArgs(
- *Invocation, CC1Args.data(), CC1Args.data() + CC1Args.size(),
- *Diagnostics);
- Invocation->getFrontendOpts().DisableFree = false;
- return Invocation;
-}
-
-/// \brief Runs the specified clang tool action and returns whether it executed
-/// successfully.
-static bool RunInvocation(const char *BinaryName,
- clang::driver::Compilation *Compilation,
- clang::CompilerInvocation *Invocation,
- const clang::driver::ArgStringList &CC1Args,
- clang::FrontendAction *ToolAction) {
- llvm::OwningPtr<clang::FrontendAction> ScopedToolAction(ToolAction);
- // Show the invocation, with -v.
- if (Invocation->getHeaderSearchOpts().Verbose) {
- llvm::errs() << "clang Invocation:\n";
- Compilation->PrintJob(llvm::errs(), Compilation->getJobs(), "\n", true);
- llvm::errs() << "\n";
- }
-
- // Create a compiler instance to handle the actual work.
- clang::CompilerInstance Compiler;
- Compiler.setInvocation(Invocation);
-
- // Create the compilers actual diagnostics engine.
- Compiler.createDiagnostics(CC1Args.size(),
- const_cast<char**>(CC1Args.data()));
- if (!Compiler.hasDiagnostics())
- return false;
-
- // Infer the builtin include path if unspecified.
- if (Compiler.getHeaderSearchOpts().UseBuiltinIncludes &&
- Compiler.getHeaderSearchOpts().ResourceDir.empty()) {
- // This just needs to be some symbol in the binary.
- void *const SymbolAddr = &StaticSymbol;
- Compiler.getHeaderSearchOpts().ResourceDir =
- clang::CompilerInvocation::GetResourcesPath(BinaryName, SymbolAddr);
- }
-
- const bool Success = Compiler.ExecuteAction(*ToolAction);
- return Success;
-}
-
-/// \brief Converts a string vector representing a Command line into a C
-/// string vector representing the Argv (including the trailing NULL).
-std::vector<char*> CommandLineToArgv(const std::vector<std::string> *Command) {
- std::vector<char*> Result(Command->size() + 1);
- for (std::vector<char*>::size_type I = 0; I < Command->size(); ++I) {
- Result[I] = const_cast<char*>((*Command)[I].c_str());
- }
- Result[Command->size()] = NULL;
- return Result;
-}
-
-bool RunToolWithFlags(
- clang::FrontendAction *ToolAction, int Args, char *Argv[]) {
- ValidateArgv(Args, Argv);
- const llvm::OwningPtr<clang::Diagnostic> Diagnostics(NewTextDiagnostics());
- const llvm::OwningPtr<clang::driver::Driver> Driver(
- NewDriver(Diagnostics.get(), Argv[0]));
- const llvm::OwningPtr<clang::driver::Compilation> Compilation(
- Driver->BuildCompilation(llvm::ArrayRef<const char*>(Argv, Args)));
- const clang::driver::ArgStringList *const CC1Args = GetCC1Arguments(
- Diagnostics.get(), Compilation.get());
- if (CC1Args == NULL) {
- return false;
- }
- llvm::OwningPtr<clang::CompilerInvocation> Invocation(
- NewInvocation(Diagnostics.get(), *CC1Args));
- return RunInvocation(Argv[0], Compilation.get(), Invocation.take(),
- *CC1Args, ToolAction);
-}
-
-/// \brief Runs 'ToolAction' on the code specified by 'FileContents'.
-///
-/// \param FileContents A mapping from file name to source code. For each
-/// entry a virtual file mapping will be created when running the tool.
-bool RunToolWithFlagsOnCode(
- const std::vector<std::string> &CommandLine,
- const std::map<std::string, std::string> &FileContents,
- clang::FrontendAction *ToolAction) {
- const std::vector<char*> Argv = CommandLineToArgv(&CommandLine);
- const char *const BinaryName = Argv[0];
-
- const llvm::OwningPtr<clang::Diagnostic> Diagnostics(NewTextDiagnostics());
- const llvm::OwningPtr<clang::driver::Driver> Driver(
- NewDriver(Diagnostics.get(), BinaryName));
-
- // Since the Input is only virtual, don't check whether it exists.
- Driver->setCheckInputsExist(false);
-
- const llvm::OwningPtr<clang::driver::Compilation> Compilation(
- Driver->BuildCompilation(llvm::ArrayRef<const char*>(&Argv[0],
- Argv.size() - 1)));
- const clang::driver::ArgStringList *const CC1Args = GetCC1Arguments(
- Diagnostics.get(), Compilation.get());
- if (CC1Args == NULL) {
- return false;
- }
- llvm::OwningPtr<clang::CompilerInvocation> Invocation(
- NewInvocation(Diagnostics.get(), *CC1Args));
-
- for (std::map<std::string, std::string>::const_iterator
- It = FileContents.begin(), End = FileContents.end();
- It != End; ++It) {
- // Inject the code as the given file name into the preprocessor options.
- const llvm::MemoryBuffer *Input =
- llvm::MemoryBuffer::getMemBuffer(It->second.c_str());
- Invocation->getPreprocessorOpts().addRemappedFile(It->first.c_str(), Input);
- }
-
- return RunInvocation(BinaryName, Compilation.get(),
- Invocation.take(), *CC1Args, ToolAction);
-}
-
-bool RunSyntaxOnlyToolOnCode(
- clang::FrontendAction *ToolAction, llvm::StringRef Code) {
- const char *const FileName = "input.cc";
- const char *const CommandLine[] = {
- "clang-tool", "-fsyntax-only", FileName
- };
- std::map<std::string, std::string> FileContents;
- FileContents[FileName] = Code;
- return RunToolWithFlagsOnCode(
- std::vector<std::string>(
- CommandLine,
- CommandLine + sizeof(CommandLine)/sizeof(CommandLine[0])),
- FileContents, ToolAction);
-}
-
-namespace {
-
-// A CompileCommandHandler implementation that finds compile commands for a
-// specific input file.
-//
-// FIXME: Implement early exit when JsonCompileCommandLineParser supports it.
-class FindHandler : public clang::tooling::CompileCommandHandler {
- public:
- explicit FindHandler(llvm::StringRef File)
- : FileToMatch(File), FoundMatchingCommand(false) {}
-
- virtual void EndTranslationUnits() {
- if (!FoundMatchingCommand && ErrorMessage.empty()) {
- ErrorMessage = "ERROR: No matching command found.";
- }
- }
-
- virtual void EndTranslationUnit() {
- if (File == FileToMatch) {
- FoundMatchingCommand = true;
- MatchingCommand.Directory = Directory;
- MatchingCommand.CommandLine = UnescapeJsonCommandLine(Command);
- }
- }
-
- virtual void HandleKeyValue(llvm::StringRef Key, llvm::StringRef Value) {
- if (Key == "directory") { Directory = Value; }
- else if (Key == "file") { File = Value; }
- else if (Key == "command") { Command = Value; }
- else {
- ErrorMessage = (llvm::Twine("Unknown key: \"") + Key + "\"").str();
- }
- }
-
- const llvm::StringRef FileToMatch;
- bool FoundMatchingCommand;
- CompileCommand MatchingCommand;
- std::string ErrorMessage;
-
- llvm::StringRef Directory;
- llvm::StringRef File;
- llvm::StringRef Command;
-};
-
-} // end namespace
-
-CompileCommand FindCompileArgsInJsonDatabase(
- llvm::StringRef FileName, llvm::StringRef JsonDatabase,
- std::string &ErrorMessage) {
- FindHandler find_handler(FileName);
- JsonCompileCommandLineParser parser(JsonDatabase, &find_handler);
- if (!parser.Parse()) {
- ErrorMessage = parser.GetErrorMessage();
- return CompileCommand();
- }
- return find_handler.MatchingCommand;
-}
-
-/// \brief Returns the absolute path of 'File', by prepending it with
-/// 'BaseDirectory' if 'File' is not absolute. Otherwise returns 'File'.
-/// If 'File' starts with "./", the returned path will not contain the "./".
-/// Otherwise, the returned path will contain the literal path-concatenation of
-/// 'BaseDirectory' and 'File'.
-///
-/// \param File Either an absolute or relative path.
-/// \param BaseDirectory An absolute path.
-static std::string GetAbsolutePath(
- llvm::StringRef File, llvm::StringRef BaseDirectory) {
- assert(llvm::sys::path::is_absolute(BaseDirectory));
- if (llvm::sys::path::is_absolute(File)) {
- return File;
- }
- llvm::StringRef RelativePath(File);
- if (RelativePath.startswith("./")) {
- RelativePath = RelativePath.substr(strlen("./"));
- }
- llvm::SmallString<1024> AbsolutePath(BaseDirectory);
- llvm::sys::path::append(AbsolutePath, RelativePath);
- return AbsolutePath.str();
-}
-
-FrontendActionFactory::~FrontendActionFactory() {}
-
-ClangTool::ClangTool(int argc, char **argv) {
- if (argc < 3) {
- llvm::outs() << "Usage: " << argv[0] << " <cmake-output-dir> "
- << "<file1> <file2> ...\n";
- exit(1);
- }
- llvm::SmallString<1024> JsonDatabasePath(argv[1]);
- llvm::sys::path::append(JsonDatabasePath, "compile_commands.json");
- llvm::error_code Result =
- llvm::MemoryBuffer::getFile(JsonDatabasePath, JsonDatabase);
- if (Result != 0) {
- llvm::outs() << "Error while opening JSON database: " << Result.message()
- << "\n";
- exit(1);
- }
- Files = std::vector<std::string>(argv + 2, argv + argc);
-}
-
-int ClangTool::Run(FrontendActionFactory *ActionFactory) {
- llvm::StringRef BaseDirectory(::getenv("PWD"));
- bool ProcessingFailed = false;
- for (unsigned I = 0; I < Files.size(); ++I) {
- llvm::SmallString<1024> File(GetAbsolutePath(Files[I], BaseDirectory));
- llvm::outs() << "Processing " << File << ".\n";
- std::string ErrorMessage;
- clang::tooling::CompileCommand LookupResult =
- clang::tooling::FindCompileArgsInJsonDatabase(
- File.str(), JsonDatabase->getBuffer(), ErrorMessage);
- if (!LookupResult.CommandLine.empty()) {
- if (!LookupResult.Directory.empty()) {
- // FIXME: What should happen if CommandLine includes -working-directory
- // as well?
- LookupResult.CommandLine.push_back(
- "-working-directory=" + LookupResult.Directory);
- }
- if (!clang::tooling::RunToolWithFlags(
- ActionFactory->New(),
- LookupResult.CommandLine.size(),
- &clang::tooling::CommandLineToArgv(
- &LookupResult.CommandLine)[0])) {
- llvm::outs() << "Error while processing " << File << ".\n";
- ProcessingFailed = true;
- }
- } else {
- // FIXME: There are two use cases here: doing a fuzzy
- // "find . -name '*.cc' |xargs tool" match, where as a user I don't care
- // about the .cc files that were not found, and the use case where I
- // specify all files I want to run over explicitly, where this should
- // be an error. We'll want to add an option for this.
- llvm::outs() << "Skipping " << File << ". Command line not found.\n";
- }
- }
- return ProcessingFailed ? 1 : 0;
-}
-
-} // end namespace tooling
-} // end namespace clang
-
diff --git a/test/Tooling/remove-cstr-calls.cpp b/test/Tooling/remove-cstr-calls.cpp
deleted file mode 100644
index 701683b285..0000000000
--- a/test/Tooling/remove-cstr-calls.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: rm -rf %t
-// RUN: mkdir %t
-// RUN: echo '[{"directory":".","command":"clang++ '$(llvm-config --cppflags all)' -c %s","file":"%s"}]' > %t/compile_commands.json
-// RUN: remove-cstr-calls %t %s | FileCheck %s
-// XFAIL: *
-
-#include <string>
-
-namespace llvm { struct StringRef { StringRef(const char *p); }; }
-
-void f1(const std::string &s) {
- f1(s.c_str()); // CHECK:remove-cstr-calls.cpp:11:6:11:14:s
-}
-void f2(const llvm::StringRef r) {
- std::string s;
- f2(s.c_str()); // CHECK:remove-cstr-calls.cpp:15:6:15:14:s
-}
-void f3(const llvm::StringRef &r) {
- std::string s;
- f3(s.c_str()); // CHECK:remove-cstr-calls.cpp:19:6:19:14:s
-}
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 1fc11ab66e..cb44dc59dc 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -59,18 +59,3 @@ add_clang_unittest(Frontend
Frontend/FrontendActionTest.cpp
USED_LIBS gtest gtest_main clangFrontend
)
-
-add_clang_unittest(Tooling
- Tooling/ToolingTest.cpp
- USED_LIBS gtest gtest_main clangTooling
- )
-
-add_clang_unittest(JsonCompileCommandLineDatabase
- Tooling/JsonCompileCommandLineDatabaseTest.cpp
- USED_LIBS gtest gtest_main clangTooling
- )
-
-add_clang_unittest(ASTMatchersTest
- Tooling/ASTMatchersTest.cpp
- USED_LIBS gtest gtest_main clangTooling
- )
diff --git a/unittests/Tooling/ASTMatchersTest.cpp b/unittests/Tooling/ASTMatchersTest.cpp
deleted file mode 100644
index 933e59c9f7..0000000000
--- a/unittests/Tooling/ASTMatchersTest.cpp
+++ /dev/null
@@ -1,1604 +0,0 @@
-//===- unittest/Tooling/ASTMatchersTest.cpp - AST matcher unit tests ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Tooling/ASTMatchers.h"
-#include "gtest/gtest.h"
-
-namespace clang {
-namespace tooling {
-
-using match::AnyOf;
-using match::AllOf;
-using match::ArgumentCountIs;
-using match::BinaryOperator;
-using match::BoolLiteral;
-using match::StringLiteral;
-using match::IntegerLiteral;
-using match::CharacterLiteral;
-using match::Call;
-using match::Callee;
-using match::Class;
-using match::CompoundStatement;
-using match::ConstructorCall;
-using match::DeclarationMatcher;
-using match::DefaultArgument;
-using match::ConditionalOperator;
-using match::DeclarationReference;
-using match::Expression;
-using match::Equals;
-using match::For;
-using match::Has;
-using match::HasAnyArgument;
-using match::HasAnyParameter;
-using match::HasAnySubstatement;
-using match::HasArgument;
-using match::HasBody;
-using match::HasCondition;
-using match::HasDeclaration;
-using match::HasDescendant;
-using match::HasEitherOperand;
-using match::HasFalseExpression;
-using match::HasInitializer;
-using match::HasLHS;
-using match::HasName;
-using match::HasUnaryOperand;
-using match::HasOperatorName;
-using match::HasOverloadedOperatorName;
-using match::HasParameter;
-using match::HasRHS;
-using match::HasTrueExpression;
-using match::HasType;
-using match::Id;
-using match::If;
-using match::IsArrow;
-using match::IsDefinition;
-using match::IsDerivedFrom;
-using match::MemberExpression;
-using match::Method;
-using match::Not;
-using match::OfClass;
-using match::On;
-using match::OverloadedOperatorCall;
-using match::PointsTo;
-using match::References;
-using match::StatementCountIs;
-using match::StatementMatcher;
-using match::ThisPointerType;
-using match::To;
-using match::TypeMatcher;
-using match::UnaryOperator;
-using match::Variable;
-
-class BoundNodesCallback {
- public:
- virtual ~BoundNodesCallback() {}
- virtual bool Run(const BoundNodes *BoundNodes) = 0;
-};
-
-// If 'FindResultVerifier' is not NULL, sets *Verified to the result of
-// running 'FindResultVerifier' with the bound nodes as argument.
-// If 'FindResultVerifier' is NULL, sets *Verified to true when Run is called.
-class VerifyMatch : public MatchFinder::MatchCallback {
- public:
- VerifyMatch(BoundNodesCallback *FindResultVerifier, bool *Verified)
- : Verified(Verified), FindResultReviewer(FindResultVerifier) {}
-
- virtual void Run(const MatchFinder::MatchResult &Result) {
- if (FindResultReviewer != NULL) {
- *Verified = FindResultReviewer->Run(&Result.Nodes);
- } else {
- *Verified = true;
- }
- }
-
- private:
- bool *const Verified;
- BoundNodesCallback *const FindResultReviewer;
-};
-
-template <typename T>
-testing::AssertionResult MatchesConditionally(
- const std::string &Code, const T &AMatcher, bool ExpectMatch) {
- bool Found = false;
- MatchFinder Finder;
- Finder.AddMatcher(AMatcher, new VerifyMatch(NULL, &Found));
- if (!Finder.FindAll(Code)) {
- return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
- }
- if (!Found && ExpectMatch) {
- return testing::AssertionFailure()
- << "Could not find match in \"" << Code << "\"";
- } else if (Found && !ExpectMatch) {
- return testing::AssertionFailure()
- << "Found unexpected match in \"" << Code << "\"";
- }
- return testing::AssertionSuccess();
-}
-
-template <typename T>
-testing::AssertionResult Matches(const std::string &Code, const T &AMatcher) {
- return MatchesConditionally(Code, AMatcher, true);
-}
-
-template <typename T>
-testing::AssertionResult NotMatches(
- const std::string &Code, const T &AMatcher) {
- return MatchesConditionally(Code, AMatcher, false);
-}
-
-template <typename T>
-testing::AssertionResult MatchAndVerifyResultConditionally(
- const std::string &Code, const T &AMatcher,
- BoundNodesCallback *FindResultVerifier, bool ExpectResult) {
- llvm::OwningPtr<BoundNodesCallback> ScopedVerifier(FindResultVerifier);
- bool VerifiedResult = false;
- MatchFinder Finder;
- Finder.AddMatcher(
- AMatcher, new VerifyMatch(FindResultVerifier, &VerifiedResult));
- if (!Finder.FindAll(Code)) {
- return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
- }
- if (!VerifiedResult && ExpectResult) {
- return testing::AssertionFailure()
- << "Could not verify result in \"" << Code << "\"";
- } else if (VerifiedResult && !ExpectResult) {
- return testing::AssertionFailure()
- << "Verified unexpected result in \"" << Code << "\"";
- }
- return testing::AssertionSuccess();
-}
-
-// FIXME: Find better names for these functions (or document what they
-// do more precisely).
-template <typename T>
-testing::AssertionResult MatchAndVerifyResultTrue(
- const std::string &Code, const T &AMatcher,
- BoundNodesCallback *FindResultVerifier) {
- return MatchAndVerifyResultConditionally(
- Code, AMatcher, FindResultVerifier, true);
-}
-
-template <typename T>
-testing::AssertionResult MatchAndVerifyResultFalse(
- const std::string &Code, const T &AMatcher,
- BoundNodesCallback *FindResultVerifier) {
- return MatchAndVerifyResultConditionally(
- Code, AMatcher, FindResultVerifier, false);
-}
-
-TEST(HasNameDeathTest, DiesOnEmptyName) {
- ASSERT_DEBUG_DEATH({
- DeclarationMatcher HasEmptyName = Class(HasName(""));
- EXPECT_TRUE(NotMatches("class X {};", HasEmptyName));
- }, "");
-}
-
-TEST(IsDerivedFromDeathTest, DiesOnEmptyBaseName) {
- ASSERT_DEBUG_DEATH({
- DeclarationMatcher IsDerivedFromEmpty = Class(IsDerivedFrom(""));
- EXPECT_TRUE(NotMatches("class X {};", IsDerivedFromEmpty));
- }, "");
-}
-
-TEST(DeclarationMatcher, MatchClass) {
- DeclarationMatcher ClassMatcher(Class());
- // Even for an empty string there are classes in the AST.
- EXPECT_TRUE(Matches("", ClassMatcher));
-
- DeclarationMatcher ClassX = Class(Class(HasName("X")));
- EXPECT_TRUE(Matches("class X;", ClassX));
- EXPECT_TRUE(Matches("class X {};", ClassX));
- EXPECT_TRUE(Matches("template<class T> class X {};", ClassX));
- EXPECT_TRUE(NotMatches("", ClassX));
-}
-
-TEST(DeclarationMatcher, ClassIsDerived) {
- DeclarationMatcher IsDerivedFromX = Class(IsDerivedFrom("X"));
-
- EXPECT_TRUE(Matches("class X {}; class Y : public X {};", IsDerivedFromX));
- EXPECT_TRUE(Matches("class X {}; class Y : public X {};", IsDerivedFromX));
- EXPECT_TRUE(Matches("class X {};", IsDerivedFromX));
- EXPECT_TRUE(Matches("class X;", IsDerivedFromX));
- EXPECT_TRUE(NotMatches("class Y;", IsDerivedFromX));
- EXPECT_TRUE(NotMatches("", IsDerivedFromX));
-
- DeclarationMatcher ZIsDerivedFromX =
- Class(HasName("Z"), IsDerivedFrom("X"));
- EXPECT_TRUE(
- Matches("class X {}; class Y : public X {}; class Z : public Y {};",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("class X {};"
- "template<class T> class Y : public X {};"
- "class Z : public Y<int> {};", ZIsDerivedFromX));
- EXPECT_TRUE(Matches("class X {}; template<class T> class Z : public X {};",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("template<class T> class X {}; "
- "template<class T> class Z : public X<T> {};",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("template<class T, class U=T> class X {}; "
- "template<class T> class Z : public X<T> {};",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- NotMatches("template<class X> class A { class Z : public X {}; };",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("template<class X> class A { public: class Z : public X {}; }; "
- "class X{}; void y() { A<X>::Z z; }", ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("template <class T> class X {}; "
- "template<class Y> class A { class Z : public X<Y> {}; };",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- NotMatches("template<template<class T> class X> class A { "
- " class Z : public X<int> {}; };", ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("template<template<class T> class X> class A { "
- " public: class Z : public X<int> {}; }; "
- "template<class T> class X {}; void y() { A<X>::Z z; }",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- NotMatches("template<class X> class A { class Z : public X::D {}; };",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("template<class X> class A { public: "
- " class Z : public X::D {}; }; "
- "class Y { public: class X {}; typedef X D; }; "
- "void y() { A<Y>::Z z; }", ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("class X {}; typedef X Y; class Z : public Y {};",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("template<class T> class Y { typedef typename T::U X; "
- " class Z : public X {}; };", ZIsDerivedFromX));
- EXPECT_TRUE(Matches("class X {}; class Z : public ::X {};",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- NotMatches("template<class T> class X {}; "
- "template<class T> class A { class Z : public X<T>::D {}; };",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("template<class T> class X { public: typedef X<T> D; }; "
- "template<class T> class A { public: "
- " class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- NotMatches("template<class X> class A { class Z : public X::D::E {}; };",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("class X {}; class Y : public X {}; "
- "typedef Y V; typedef V W; class Z : public W {};",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("template<class T, class U> class X {}; "
- "template<class T> class A { class Z : public X<T, int> {}; };",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- NotMatches("template<class X> class D { typedef X A; typedef A B; "
- " typedef B C; class Z : public C {}; };",
- ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("class X {}; typedef X A; typedef A B; "
- "class Z : public B {};", ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("class X {}; typedef X A; typedef A B; typedef B C; "
- "class Z : public C {};", ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("class U {}; typedef U X; typedef X V; "
- "class Z : public V {};", ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("class Base {}; typedef Base X; "
- "class Z : public Base {};", ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("class Base {}; typedef Base Base2; typedef Base2 X; "
- "class Z : public Base {};", ZIsDerivedFromX));
- EXPECT_TRUE(
- NotMatches("class Base {}; class Base2 {}; typedef Base2 X; "
- "class Z : public Base {};", ZIsDerivedFromX));
- EXPECT_TRUE(
- Matches("class A {}; typedef A X; typedef A Y; "
- "class Z : public Y {};", ZIsDerivedFromX));
- EXPECT_TRUE(
- NotMatches("template <typename T> class Z;"
- "template <> class Z<void> {};"
- "template <typename T> class Z : public Z<void> {};",
- IsDerivedFromX));
- EXPECT_TRUE(
- Matches("template <typename T> class X;"
- "template <> class X<void> {};"
- "template <typename T> class X : public X<void> {};",
- IsDerivedFromX));
- EXPECT_TRUE(Matches(
- "class X {};"
- "template <typename T> class Z;"
- "template <> class Z<void> {};"
- "template <typename T> class Z : public Z<void>, public X {};",
- ZIsDerivedFromX));
-
- // FIXME: Once we have better matchers for template type matching,
- // get rid of the Variable(...) matching and match the right template
- // declarations directly.
- const char *RecursiveTemplateOneParameter =
- "class Base1 {}; class Base2 {};"
- "template <typename T> class Z;"
- "template <> class Z<void> : public Base1 {};"
- "template <> class Z<int> : public Base2 {};"
- "template <> class Z<float> : public Z<void> {};"
- "template <> class Z<double> : public Z<int> {};"
- "template <typename T> class Z : public Z<float>, public Z<double> {};"
- "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
- EXPECT_TRUE(Matches(
- RecursiveTemplateOneParameter,
- Variable(HasName("z_float"),
- HasInitializer(HasType(Class(IsDerivedFrom("Base1")))))));
- EXPECT_TRUE(NotMatches(
- RecursiveTemplateOneParameter,
- Variable(
- HasName("z_float"),
- HasInitializer(HasType(Class(IsDerivedFrom("Base2")))))));
- EXPECT_TRUE(Matches(
- RecursiveTemplateOneParameter,
- Variable(
- HasName("z_char"),
- HasInitializer(HasType(Class(IsDerivedFrom("Base1"),
- IsDerivedFrom("Base2")))))));
-
- const char *RecursiveTemplateTwoParameters =
- "class Base1 {}; class Base2 {};"
- "template <typename T1, typename T2> class Z;"
- "template <typename T> class Z<void, T> : public Base1 {};"
- "template <typename T> class Z<int, T> : public Base2 {};"
- "template <typename T> class Z<float, T> : public Z<void, T> {};"
- "template <typename T> class Z<double, T> : public Z<int, T> {};"
- "template <typename T1, typename T2> class Z : "
- " public Z<float, T2>, public Z<double, T2> {};"
- "void f() { Z<float, void> z_float; Z<double, void> z_double; "
- " Z<char, void> z_char; }";
- EXPECT_TRUE(Matches(
- RecursiveTemplateTwoParameters,
- Variable(
- HasName("z_float"),
- HasInitializer(HasType(Class(IsDerivedFrom("Base1")))))));
- EXPECT_TRUE(NotMatches(
- RecursiveTemplateTwoParameters,
- Variable(
- HasName("z_float"),
- HasInitializer(HasType(Class(IsDerivedFrom("Base2")))))));
- EXPECT_TRUE(Matches(
- RecursiveTemplateTwoParameters,
- Variable(
- HasName("z_char"),
- HasInitializer(HasType(Class(IsDerivedFrom("Base1"),
- IsDerivedFrom("Base2")))))));
-}
-
-TEST(DeclarationMatcher, MatchAnyOf) {
- DeclarationMatcher YOrZDerivedFromX =
- Class(AnyOf(HasName("Y"), AllOf(IsDerivedFrom("X"), HasName("Z"))));
-
- EXPECT_TRUE(
- Matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
- EXPECT_TRUE(Matches("class Y {};", YOrZDerivedFromX));
- EXPECT_TRUE(
- NotMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
- EXPECT_TRUE(NotMatches("class Z {};", YOrZDerivedFromX));
-
- DeclarationMatcher XOrYOrZOrU =
- Class(AnyOf(HasName("X"), HasName("Y"), HasName("Z"), HasName("U")));
-
- EXPECT_TRUE(Matches("class X {};", XOrYOrZOrU));
- EXPECT_TRUE(Matches("class Y {};", XOrYOrZOrU));
- EXPECT_TRUE(Matches("class Z {};", XOrYOrZOrU));
- EXPECT_TRUE(Matches("class U {};", XOrYOrZOrU));
- EXPECT_TRUE(NotMatches("class A {};", XOrYOrZOrU));
-}
-
-TEST(DeclarationMatcher, MatchHas) {
- DeclarationMatcher HasClassX = Class(Has(Class(HasName("X"))));
-
- EXPECT_TRUE(Matches("class Y { class X {}; };", HasClassX));
- EXPECT_TRUE(Matches("class X {};", HasClassX));
-
- DeclarationMatcher YHasClassX =
- Class(HasName("Y"), Has(Class(HasName("X"))));
- EXPECT_TRUE(Matches("class Y { class X {}; };", YHasClassX));
- EXPECT_TRUE(NotMatches("class X {};", YHasClassX));
- EXPECT_TRUE(
- NotMatches("class Y { class Z { class X {}; }; };", YHasClassX));
-}
-
-TEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
- DeclarationMatcher Recursive =
- Class(
- Has(Class(
- Has(Class(
- HasName("X"))),
- Has(Class(
- HasName("Y"))),
- HasName("Z"))),
- Has(Class(
- Has(Class(
- HasName("A"))),
- Has(Class(
- HasName("B"))),
- HasName("C"))),
- HasName("F"));
-
- EXPECT_TRUE(Matches(
- "class F {"
- " class Z {"
- " class X {};"
- " class Y {};"
- " };"
- " class C {"
- " class A {};"
- " class B {};"
- " };"
- "};", Recursive));
-
- EXPECT_TRUE(Matches(
- "class F {"
- " class Z {"
- " class A {};"
- " class X {};"
- " class Y {};"
- " };"
- " class C {"
- " class X {};"
- " class A {};"
- " class B {};"
- " };"
- "};", Recursive));
-
- EXPECT_TRUE(Matches(
- "class O1 {"
- " class O2 {"
- " class F {"
- " class Z {"
- " class A {};"
- " class X {};"
- " class Y {};"
- " };"
- " class C {"
- " class X {};"
- " class A {};"
- " class B {};"
- " };"
- " };"
- " };"
- "};", Recursive));
-}
-
-TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
- DeclarationMatcher Recursive =
- Class(
- AnyOf(
- Has(Class(
- AnyOf(
- Has(Class(
- HasName("X"))),
- Has(Class(
- HasName("Y"))),
- HasName("Z")))),
- Has(Class(
- AnyOf(
- HasName("C"),
- Has(Class(
- HasName("A"))),
- Has(Class(
- HasName("B")))))),
- HasName("F")));
-
- EXPECT_TRUE(Matches("class F {};", Recursive));
- EXPECT_TRUE(Matches("class Z {};", Recursive));
- EXPECT_TRUE(Matches("class C {};", Recursive));
- EXPECT_TRUE(Matches("class M { class N { class X {}; }; };", Recursive));
- EXPECT_TRUE(Matches("class M { class N { class B {}; }; };", Recursive));
- EXPECT_TRUE(
- Matches("class O1 { class O2 {"
- " class M { class N { class B {}; }; }; "
- "}; };", Recursive));
-}
-
-TEST(DeclarationMatcher, MatchNot) {
- DeclarationMatcher NotClassX =
- Class(
- IsDerivedFrom("Y"),
- Not(HasName("Y")),
- Not(HasName("X")));
- EXPECT_TRUE(NotMatches("", NotClassX));
- EXPECT_TRUE(NotMatches("class Y {};", NotClassX));
- EXPECT_TRUE(Matches("class Y {}; class Z : public Y {};", NotClassX));
- EXPECT_TRUE(NotMatches("class Y {}; class X : public Y {};", NotClassX));
- EXPECT_TRUE(
- NotMatches("class Y {}; class Z {}; class X : public Y {};",
- NotClassX));
-
- DeclarationMatcher ClassXHasNotClassY =
- Class(
- HasName("X"),
- Has(Class(HasName("Z"))),
- Not(
- Has(Class(HasName("Y")))));
- EXPECT_TRUE(Matches("class X { class Z {}; };", ClassXHasNotClassY));
- EXPECT_TRUE(NotMatches("class X { class Y {}; class Z {}; };",
- ClassXHasNotClassY));
-}
-
-TEST(DeclarationMatcher, HasDescendant) {
- DeclarationMatcher ZDescendantClassX =
- Class(
- HasDescendant(Class(HasName("X"))),
- HasName("Z"));
- EXPECT_TRUE(Matches("class Z { class X {}; };", ZDescendantClassX));
- EXPECT_TRUE(
- Matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
- EXPECT_TRUE(
- Matches("class Z { class A { class Y { class X {}; }; }; };",
- ZDescendantClassX));
- EXPECT_TRUE(
- Matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
- ZDescendantClassX));
- EXPECT_TRUE(NotMatches("class Z {};", ZDescendantClassX));
-
- DeclarationMatcher ZDescendantClassXHasClassY =
- Class(
- HasDescendant(Class(Has(Class(HasName("Y"))),
- HasName("X"))),
- HasName("Z"));
- EXPECT_TRUE(Matches("class Z { class X { class Y {}; }; };",
- ZDescendantClassXHasClassY));
- EXPECT_TRUE(
- Matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
- ZDescendantClassXHasClassY));
- EXPECT_TRUE(NotMatches(
- "class Z {"
- " class A {"
- " class B {"
- " class X {"
- " class C {"
- " class Y {};"
- " };"
- " };"
- " }; "
- " };"
- "};", ZDescendantClassXHasClassY));
-
- DeclarationMatcher ZDescendantClassXDescendantClassY =
- Class(
- HasDescendant(Class(HasDescendant(Class(HasName("Y"))),
- HasName("X"))),
- HasName("Z"));
- EXPECT_TRUE(
- Matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
- ZDescendantClassXDescendantClassY));
- EXPECT_TRUE(Matches(
- "class Z {"
- " class A {"
- " class X {"
- " class B {"
- " class Y {};"
- " };"
- " class Y {};"
- " };"
- " };"
- "};", ZDescendantClassXDescendantClassY));
-}
-
-TEST(StatementMatcher, Has) {
- StatementMatcher HasVariableI =
- Expression(
- HasType(PointsTo(Class(HasName("X")))),
- Has(DeclarationReference(To(Variable(HasName("i"))))));
-
- EXPECT_TRUE(Matches(
- "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
- EXPECT_TRUE(NotMatches(
- "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
-}
-
-TEST(StatementMatcher, HasDescendant) {
- StatementMatcher HasDescendantVariableI =
- Expression(
- HasType(PointsTo(Class(HasName("X")))),
- HasDescendant(DeclarationReference(To(Variable(HasName("i"))))));
-
- EXPECT_TRUE(Matches(
- "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
- HasDescendantVariableI));
- EXPECT_TRUE(NotMatches(
- "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
- HasDescendantVariableI));
-}
-
-TEST(TypeMatcher, MatchesClassType) {
- TypeMatcher TypeA = HasDeclaration(Class(HasName("A")));
-
- EXPECT_TRUE(Matches("class A { public: A *a; };", TypeA));
- EXPECT_TRUE(NotMatches("class A {};", TypeA));
-
- TypeMatcher TypeDerivedFromA = HasDeclaration(Class(IsDerivedFrom("A")));
-
- EXPECT_TRUE(Matches("class A {}; class B : public A { public: B *b; };",
- TypeDerivedFromA));
- EXPECT_TRUE(NotMatches("class A {};", TypeA));
-
- TypeMatcher TypeAHasClassB = HasDeclaration(
- Class(HasName("A"), Has(Class(HasName("B")))));
-
- EXPECT_TRUE(
- Matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
-}
-
-// Returns whether 'bound_nodes' contain a Decl for bound to 'id', which
-// can be dynamically casted to T.
-template <typename T>
-class VerifyIdIsBoundToDecl : public BoundNodesCallback {
- public:
- explicit VerifyIdIsBoundToDecl(const std::string &Id) : Id(Id) {}
- virtual bool Run(const BoundNodes *Nodes) {
- const T *Node = Nodes->GetDeclAs<T>(Id);
- return Node != NULL;
- }
-
- private:
- const std::string Id;
-};
-template <typename T>
-class VerifyIdIsBoundToStmt : public BoundNodesCallback {
- public:
- explicit VerifyIdIsBoundToStmt(const std::string &Id) : Id(Id) {}
- virtual bool Run(const BoundNodes *Nodes) {
- const T *Node = Nodes->GetStmtAs<T>(Id);
- return Node != NULL;
- }
- private:
- const std::string Id;
-};
-
-TEST(Matcher, BindMatchedNodes) {
- DeclarationMatcher ClassX = Has(Id("x", Class(HasName("X"))));
-
- EXPECT_TRUE(MatchAndVerifyResultTrue("class X {};",
- ClassX, new VerifyIdIsBoundToDecl<clang::CXXRecordDecl>("x")));
-
- EXPECT_TRUE(MatchAndVerifyResultFalse("class X {};",
- ClassX, new VerifyIdIsBoundToDecl<clang::CXXRecordDecl>("other-id")));
-
- TypeMatcher TypeAHasClassB = HasDeclaration(
- Class(HasName("A"), Has(Id("b", Class(HasName("B"))))));
-
- EXPECT_TRUE(MatchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
- TypeAHasClassB,
- new VerifyIdIsBoundToDecl<clang::Decl>("b")));
-
- StatementMatcher MethodX = Id("x", Call(Callee(Method(HasName("x")))));
-
- EXPECT_TRUE(MatchAndVerifyResultTrue("class A { void x() { x(); } };",
- MethodX,
- new VerifyIdIsBoundToStmt<clang::CXXMemberCallExpr>("x")));
-}
-
-TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
- TypeMatcher ClassX = HasDeclaration(Class(HasName("X")));
- EXPECT_TRUE(
- Matches("class X {}; void y(X &x) { x; }", Expression(HasType(ClassX))));
- EXPECT_TRUE(
- NotMatches("class X {}; void y(X *x) { x; }",
- Expression(HasType(ClassX))));
- EXPECT_TRUE(
- Matches("class X {}; void y(X *x) { x; }",
- Expression(HasType(PointsTo(ClassX)))));
-}
-
-TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
- TypeMatcher ClassX = HasDeclaration(Class(HasName("X")));
- EXPECT_TRUE(
- Matches("class X {}; void y() { X x; }", Variable(HasType(ClassX))));
- EXPECT_TRUE(
- NotMatches("class X {}; void y() { X *x; }", Variable(HasType(ClassX))));
- EXPECT_TRUE(
- Matches("class X {}; void y() { X *x; }",
- Variable(HasType(PointsTo(ClassX)))));
-}
-
-TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
- DeclarationMatcher ClassX = Class(HasName("X"));
- EXPECT_TRUE(
- Matches("class X {}; void y(X &x) { x; }", Expression(HasType(ClassX))));
- EXPECT_TRUE(
- NotMatches("class X {}; void y(X *x) { x; }",
- Expression(HasType(ClassX))));
-}
-
-TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
- DeclarationMatcher ClassX = Class(HasName("X"));
- EXPECT_TRUE(
- Matches("class X {}; void y() { X x; }", Variable(HasType(ClassX))));
- EXPECT_TRUE(
- NotMatches("class X {}; void y() { X *x; }", Variable(HasType(ClassX))));
-}
-
-TEST(Matcher, Call) {
- // FIXME: Do we want to overload Call() to directly take
- // Matcher<clang::Decl>, too?
- StatementMatcher MethodX = Call(HasDeclaration(Method(HasName("x"))));
-
- EXPECT_TRUE(Matches("class Y { void x() { x(); } };", MethodX));
- EXPECT_TRUE(NotMatches("class Y { void x() {} };", MethodX));
-
- StatementMatcher MethodOnY = Call(On(HasType(Class(HasName("Y")))));
-
- EXPECT_TRUE(
- Matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
- MethodOnY));
- EXPECT_TRUE(
- Matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
- MethodOnY));
- EXPECT_TRUE(
- NotMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
- MethodOnY));
- EXPECT_TRUE(
- NotMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
- MethodOnY));
- EXPECT_TRUE(
- NotMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
- MethodOnY));
-
- StatementMatcher MethodOnYPointer =
- Call(On(HasType(PointsTo(Class(HasName("Y"))))));
-
- EXPECT_TRUE(
- Matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
- MethodOnYPointer));
- EXPECT_TRUE(
- Matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
- MethodOnYPointer));
- EXPECT_TRUE(
- Matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
- MethodOnYPointer));
- EXPECT_TRUE(
- NotMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
- MethodOnYPointer));
- EXPECT_TRUE(
- NotMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
- MethodOnYPointer));
-}
-
-TEST(Matcher, OverloadedOperatorCall) {
- StatementMatcher OpCall = OverloadedOperatorCall();
- // Unary operator
- EXPECT_TRUE(Matches("class Y { }; "
- "bool operator!(Y x) { return false; }; "
- "Y y; bool c = !y;", OpCall));
- // No match -- special operators like "new", "delete"
- // FIXME: operator new takes size_t, for which we need stddef.h, for which
- // we need to figure out include paths in the test.
- // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
- // "class Y { }; "
- // "void *operator new(size_t size) { return 0; } "
- // "Y *y = new Y;", OpCall));
- EXPECT_TRUE(NotMatches("class Y { }; "
- "void operator delete(void *p) { } "
- "void a() {Y *y = new Y; delete y;}", OpCall));
- // Binary operator
- EXPECT_TRUE(Matches("class Y { }; "
- "bool operator&&(Y x, Y y) { return true; }; "
- "Y a; Y b; bool c = a && b;",
- OpCall));
- // No match -- normal operator, not an overloaded one.
- EXPECT_TRUE(NotMatches("bool x = true, y = true; bool t = x && y;", OpCall));
- EXPECT_TRUE(NotMatches("int t = 5 << 2;", OpCall));
-}
-
-TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
- StatementMatcher OpCallAndAnd =
- OverloadedOperatorCall(HasOverloadedOperatorName("&&"));
- EXPECT_TRUE(Matches("class Y { }; "
- "bool operator&&(Y x, Y y) { return true; }; "
- "Y a; Y b; bool c = a && b;", OpCallAndAnd));
- StatementMatcher OpCallLessLess =
- OverloadedOperatorCall(HasOverloadedOperatorName("<<"));
- EXPECT_TRUE(NotMatches("class Y { }; "
- "bool operator&&(Y x, Y y) { return true; }; "
- "Y a; Y b; bool c = a && b;",
- OpCallLessLess));
-}
-
-TEST(Matcher, ThisPointerType) {
- StatementMatcher MethodOnY = Call(ThisPointerType(Class(HasName("Y"))));
-
- EXPECT_TRUE(
- Matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
- MethodOnY));
- EXPECT_TRUE(
- Matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
- MethodOnY));
- EXPECT_TRUE(
- Matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
- MethodOnY));
- EXPECT_TRUE(
- Matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
- MethodOnY));
- EXPECT_TRUE(
- Matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
- MethodOnY));
-
- EXPECT_TRUE(Matches(
- "class Y {"
- " public: virtual void x();"
- "};"
- "class X : public Y {"
- " public: virtual void x();"
- "};"
- "void z() { X *x; x->Y::x(); }", MethodOnY));
-}
-
-TEST(Matcher, VariableUsage) {
- StatementMatcher Reference =
- DeclarationReference(To(
- Variable(HasInitializer(
- Call(ThisPointerType(Class(HasName("Y"))))))));
-
- EXPECT_TRUE(Matches(
- "class Y {"
- " public:"
- " bool x() const;"
- "};"
- "void z(const Y &y) {"
- " bool b = y.x();"
- " if (b) {}"
- "}", Reference));
-
- EXPECT_TRUE(NotMatches(
- "class Y {"
- " public:"
- " bool x() const;"
- "};"
- "void z(const Y &y) {"
- " bool b = y.x();"
- "}", Reference));
-}
-
-TEST(Matcher, CalledVariable) {
- StatementMatcher CallOnVariableY = Expression(
- Call(On(DeclarationReference(To(Variable(HasName("y")))))));
-
- EXPECT_TRUE(Matches(
- "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
- EXPECT_TRUE(Matches(
- "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
- EXPECT_TRUE(Matches(
- "class Y { public: void x(); };"
- "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
- EXPECT_TRUE(Matches(
- "class Y { public: void x(); };"
- "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
- EXPECT_TRUE(NotMatches(
- "class Y { public: void x(); };"
- "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
- CallOnVariableY));
-}
-
-TEST(MemberExpression, DoesNotMatchClasses) {
- EXPECT_TRUE(NotMatches("class Y { void x() {} };", MemberExpression()));
-}
-
-TEST(MemberExpression, MatchesMemberFunctionCall) {
- EXPECT_TRUE(Matches("class Y { void x() { x(); } };", MemberExpression()));
-}
-
-TEST(MemberExpression, MatchesVariable) {
- EXPECT_TRUE(
- Matches("class Y { void x() { this->y; } int y; };", MemberExpression()));
- EXPECT_TRUE(
- Matches("class Y { void x() { y; } int y; };", MemberExpression()));
- EXPECT_TRUE(
- Matches("class Y { void x() { Y y; y.y; } int y; };",
- MemberExpression()));
-}
-
-TEST(MemberExpression, MatchesStaticVariable) {
- EXPECT_TRUE(Matches("class Y { void x() { this->y; } static int y; };",
- MemberExpression()));
- EXPECT_TRUE(NotMatches("class Y { void x() { y; } static int y; };",
- MemberExpression()));
- EXPECT_TRUE(NotMatches("class Y { void x() { Y::y; } static int y; };",
- MemberExpression()));
-}
-
-TEST(IsArrow, MatchesMemberVariablesViaArrow) {
- EXPECT_TRUE(Matches("class Y { void x() { this->y; } int y; };",
- MemberExpression(IsArrow())));
- EXPECT_TRUE(Matches("class Y { void x() { y; } int y; };",
- MemberExpression(IsArrow())));
- EXPECT_TRUE(NotMatches("class Y { void x() { (*this).y; } int y; };",
- MemberExpression(IsArrow())));
-}
-
-TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
- EXPECT_TRUE(Matches("class Y { void x() { this->y; } static int y; };",
- MemberExpression(IsArrow())));
- EXPECT_TRUE(NotMatches("class Y { void x() { y; } static int y; };",
- MemberExpression(IsArrow())));
- EXPECT_TRUE(NotMatches("class Y { void x() { (*this).y; } static int y; };",
- MemberExpression(IsArrow())));
-}
-
-TEST(IsArrow, MatchesMemberCallsViaArrow) {
- EXPECT_TRUE(Matches("class Y { void x() { this->x(); } };",
- MemberExpression(IsArrow())));
- EXPECT_TRUE(Matches("class Y { void x() { x(); } };",
- MemberExpression(IsArrow())));
- EXPECT_TRUE(NotMatches("class Y { void x() { Y y; y.x(); } };",
- MemberExpression(IsArrow())));
-}
-
-TEST(Callee, MatchesDeclarations) {
- StatementMatcher CallMethodX = Call(Callee(Method(HasName("x"))));
-
- EXPECT_TRUE(Matches("class Y { void x() { x(); } };", CallMethodX));
- EXPECT_TRUE(NotMatches("class Y { void x() {} };", CallMethodX));
-}
-
-TEST(Callee, MatchesMemberExpressions) {
- EXPECT_TRUE(Matches("class Y { void x() { this->x(); } };",
- Call(Callee(MemberExpression()))));
- EXPECT_TRUE(
- NotMatches("class Y { void x() { this->x(); } };", Call(Callee(Call()))));
-}
-
-TEST(Matcher, Argument) {
- StatementMatcher CallArgumentY = Expression(Call(
- HasArgument(0, DeclarationReference(To(Variable(HasName("y")))))));
-
- EXPECT_TRUE(Matches("void x(int) { int y; x(y); }", CallArgumentY));
- EXPECT_TRUE(
- Matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
- EXPECT_TRUE(NotMatches("void x(int) { int z; x(z); }", CallArgumentY));
-
- StatementMatcher WrongIndex = Expression(Call(
- HasArgument(42, DeclarationReference(To(Variable(HasName("y")))))));
- EXPECT_TRUE(NotMatches("void x(int) { int y; x(y); }", WrongIndex));
-}
-
-TEST(Matcher, AnyArgument) {
- StatementMatcher CallArgumentY = Expression(Call(
- HasAnyArgument(DeclarationReference(To(Variable(HasName("y")))))));
- EXPECT_TRUE(Matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
- EXPECT_TRUE(Matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
- EXPECT_TRUE(NotMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
-}
-
-TEST(Matcher, ArgumentCount) {
- StatementMatcher Call1Arg = Expression(Call(ArgumentCountIs(1)));
-
- EXPECT_TRUE(Matches("void x(int) { x(0); }", Call1Arg));
- EXPECT_TRUE(Matches("class X { void x(int) { x(0); } };", Call1Arg));
- EXPECT_TRUE(NotMatches("void x(int, int) { x(0, 0); }", Call1Arg));
-}
-
-TEST(Matcher, References) {
- DeclarationMatcher ReferenceClassX = Variable(
- HasType(References(Class(HasName("X")))));
- EXPECT_TRUE(Matches("class X {}; void y(X y) { X &x = y; }", ReferenceClassX));
- EXPECT_TRUE(
- Matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
- EXPECT_TRUE(
- NotMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
- EXPECT_TRUE(
- NotMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
-}
-
-TEST(HasParameter, CallsInnerMatcher) {
- EXPECT_TRUE(Matches("class X { void x(int) {} };",
- Method(HasParameter(0, Variable()))));
- EXPECT_TRUE(NotMatches("class X { void x(int) {} };",
- Method(HasParameter(0, HasName("x")))));
-}
-
-TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
- EXPECT_TRUE(NotMatches("class X { void x(int) {} };",
- Method(HasParameter(42, Variable()))));
-}
-
-TEST(HasType, MatchesParameterVariableTypesStrictly) {
- EXPECT_TRUE(Matches("class X { void x(X x) {} };",
- Method(HasParameter(0, HasType(Class(HasName("X")))))));
- EXPECT_TRUE(NotMatches("class X { void x(const X &x) {} };",
- Method(HasParameter(0, HasType(Class(HasName("X")))))));
- EXPECT_TRUE(Matches("class X { void x(const X *x) {} };",
- Method(HasParameter(0, HasType(PointsTo(Class(HasName("X"))))))));
- EXPECT_TRUE(Matches("class X { void x(const X &x) {} };",
- Method(HasParameter(0, HasType(References(Class(HasName("X"))))))));
-}
-
-TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
- EXPECT_TRUE(Matches("class Y {}; class X { void x(X x, Y y) {} };",
- Method(HasAnyParameter(HasType(Class(HasName("X")))))));
- EXPECT_TRUE(Matches("class Y {}; class X { void x(Y y, X x) {} };",
- Method(HasAnyParameter(HasType(Class(HasName("X")))))));
-}
-
-TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
- EXPECT_TRUE(NotMatches("class Y {}; class X { void x(int) {} };",
- Method(HasAnyParameter(HasType(Class(HasName("X")))))));
-}
-
-TEST(HasAnyParameter, DoesNotMatchThisPointer) {
- EXPECT_TRUE(NotMatches("class Y {}; class X { void x() {} };",
- Method(HasAnyParameter(HasType(PointsTo(Class(HasName("X"))))))));
-}
-
-TEST(HasName, MatchesParameterVariableDeclartions) {
- EXPECT_TRUE(Matches("class Y {}; class X { void x(int x) {} };",
- Method(HasAnyParameter(HasName("x")))));
- EXPECT_TRUE(NotMatches("class Y {}; class X { void x(int) {} };",
- Method(HasAnyParameter(HasName("x")))));
-}
-
-TEST(Matcher, ConstructorCall) {
- StatementMatcher Constructor = Expression(ConstructorCall());
-
- EXPECT_TRUE(
- Matches("class X { public: X(); }; void x() { X x; }", Constructor));
- EXPECT_TRUE(
- Matches("class X { public: X(); }; void x() { X x = X(); }",
- Constructor));
- EXPECT_TRUE(
- Matches("class X { public: X(int); }; void x() { X x = 0; }",
- Constructor));
- EXPECT_TRUE(Matches("class X {}; void x(int) { X x; }", Constructor));
-}
-
-TEST(Matcher, ConstructorArgument) {
- StatementMatcher Constructor = Expression(ConstructorCall(
- HasArgument(0, DeclarationReference(To(Variable(HasName("y")))))));
-
- EXPECT_TRUE(
- Matches("class X { public: X(int); }; void x() { int y; X x(y); }",
- Constructor));
- EXPECT_TRUE(
- Matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
- Constructor));
- EXPECT_TRUE(
- Matches("class X { public: X(int); }; void x() { int y; X x = y; }",
- Constructor));
- EXPECT_TRUE(
- NotMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
- Constructor));
-
- StatementMatcher WrongIndex = Expression(ConstructorCall(
- HasArgument(42, DeclarationReference(To(Variable(HasName("y")))))));
- EXPECT_TRUE(
- NotMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
- WrongIndex));
-}
-
-TEST(Matcher, ConstructorArgumentCount) {
- StatementMatcher Constructor1Arg =
- Expression(ConstructorCall(ArgumentCountIs(1)));
-
- EXPECT_TRUE(
- Matches("class X { public: X(int); }; void x() { X x(0); }",
- Constructor1Arg));
- EXPECT_TRUE(
- Matches("class X { public: X(int); }; void x() { X x = X(0); }",
- Constructor1Arg));
- EXPECT_TRUE(
- Matches("class X { public: X(int); }; void x() { X x = 0; }",
- Constructor1Arg));
- EXPECT_TRUE(
- NotMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
- Constructor1Arg));
-}
-
-TEST(Matcher, DefaultArgument) {
- StatementMatcher Arg = DefaultArgument();
-
- EXPECT_TRUE(Matches("void x(int, int = 0) { int y; x(y); }", Arg));
- EXPECT_TRUE(
- Matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
- EXPECT_TRUE(NotMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
-}
-
-TEST(Matcher, StringLiterals) {
- StatementMatcher Literal = Expression(StringLiteral());
- EXPECT_TRUE(Matches("const char *s = \"string\";", Literal));
- // wide string
- EXPECT_TRUE(Matches("const wchar_t *s = L\"string\";", Literal));
- // with escaped characters
- EXPECT_TRUE(Matches("const char *s = \"\x05five\";", Literal));
- // no matching -- though the data type is the same, there is no string literal
- EXPECT_TRUE(NotMatches("const char s[1] = {'a'};", Literal));
-}
-
-TEST(Matcher, CharacterLiterals) {
- StatementMatcher CharLiteral = Expression(CharacterLiteral());
- EXPECT_TRUE(Matches("const char c = 'c';", CharLiteral));
- // wide character
- EXPECT_TRUE(Matches("const char c = L'c';", CharLiteral));
- // wide character, Hex encoded, NOT MATCHED!
- EXPECT_TRUE(NotMatches("const wchar_t c = 0x2126;", CharLiteral));
- EXPECT_TRUE(NotMatches("const char c = 0x1;", CharLiteral));
-}
-
-TEST(Matcher, IntegerLiterals) {
- StatementMatcher HasIntLiteral = Expression(IntegerLiteral());
- EXPECT_TRUE(Matches("int i = 10;", HasIntLiteral));
- EXPECT_TRUE(Matches("int i = 0x1AB;", HasIntLiteral));
- EXPECT_TRUE(Matches("int i = 10L;", HasIntLiteral));
- EXPECT_TRUE(Matches("int i = 10U;", HasIntLiteral));
-
- // Non-matching cases (character literals, float and double)
- EXPECT_TRUE(NotMatches("int i = L'a';",
- HasIntLiteral)); // this is actually a character
- // literal cast to int
- EXPECT_TRUE(NotMatches("int i = 'a';", HasIntLiteral));
- EXPECT_TRUE(NotMatches("int i = 1e10;", HasIntLiteral));
- EXPECT_TRUE(NotMatches("int i = 10.0;", HasIntLiteral));
-}
-
-TEST(Matcher, Conditions) {
- StatementMatcher Condition = If(HasCondition(BoolLiteral(Equals(true))));
-
- EXPECT_TRUE(Matches("void x() { if (true) {} }", Condition));
- EXPECT_TRUE(NotMatches("void x() { if (false) {} }", Condition));
- EXPECT_TRUE(NotMatches("void x() { bool a = true; if (a) {} }", Condition));
- EXPECT_TRUE(NotMatches("void x() { if (true || false) {} }", Condition));
- EXPECT_TRUE(NotMatches("void x() { if (1) {} }", Condition));
-}
-
-TEST(MatchBinaryOperator, HasOperatorName) {
- StatementMatcher OperatorOr = BinaryOperator(HasOperatorName("||"));
-
- EXPECT_TRUE(Matches("void x() { true || false; }", OperatorOr));
- EXPECT_TRUE(NotMatches("void x() { true && false; }", OperatorOr));
-}
-
-TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
- StatementMatcher OperatorTrueFalse =
- BinaryOperator(HasLHS(BoolLiteral(Equals(true))),
- HasRHS(BoolLiteral(Equals(false))));
-
- EXPECT_TRUE(Matches("void x() { true || false; }", OperatorTrueFalse));
- EXPECT_TRUE(Matches("void x() { true && false; }", OperatorTrueFalse));
- EXPECT_TRUE(NotMatches("void x() { false || true; }", OperatorTrueFalse));
-}
-
-TEST(MatchBinaryOperator, HasEitherOperand) {
- StatementMatcher HasOperand =
- BinaryOperator(HasEitherOperand(BoolLiteral(Equals(false))));
-
- EXPECT_TRUE(Matches("void x() { true || false; }", HasOperand));
- EXPECT_TRUE(Matches("void x() { false && true; }", HasOperand));
- EXPECT_TRUE(NotMatches("void x() { true || true; }", HasOperand));
-}
-
-TEST(Matcher, BinaryOperatorTypes) {
- // Integration test that verifies the AST provides all binary operators in
- // a way we expect.
- // FIXME: Operator ','
- EXPECT_TRUE(
- Matches("void x() { 3, 4; }", BinaryOperator(HasOperatorName(","))));
- EXPECT_TRUE(
- Matches("bool b; bool c = (b = true);",
- BinaryOperator(HasOperatorName("="))));
- EXPECT_TRUE(
- Matches("bool b = 1 != 2;", BinaryOperator(HasOperatorName("!="))));
- EXPECT_TRUE(
- Matches("bool b = 1 == 2;", BinaryOperator(HasOperatorName("=="))));
- EXPECT_TRUE(Matches("bool b = 1 < 2;", BinaryOperator(HasOperatorName("<"))));
- EXPECT_TRUE(
- Matches("bool b = 1 <= 2;", BinaryOperator(HasOperatorName("<="))));
- EXPECT_TRUE(
- Matches("int i = 1 << 2;", BinaryOperator(HasOperatorName("<<"))));
- EXPECT_TRUE(
- Matches("int i = 1; int j = (i <<= 2);",
- BinaryOperator(HasOperatorName("<<="))));
- EXPECT_TRUE(Matches("bool b = 1 > 2;", BinaryOperator(HasOperatorName(">"))));
- EXPECT_TRUE(
- Matches("bool b = 1 >= 2;", BinaryOperator(HasOperatorName(">="))));
- EXPECT_TRUE(
- Matches("int i = 1 >> 2;", BinaryOperator(HasOperatorName(">>"))));
- EXPECT_TRUE(
- Matches("int i = 1; int j = (i >>= 2);",
- BinaryOperator(HasOperatorName(">>="))));
- EXPECT_TRUE(
- Matches("int i = 42 ^ 23;", BinaryOperator(HasOperatorName("^"))));
- EXPECT_TRUE(
- Matches("int i = 42; int j = (i ^= 42);",
- BinaryOperator(HasOperatorName("^="))));
- EXPECT_TRUE(
- Matches("int i = 42 % 23;", BinaryOperator(HasOperatorName("%"))));
- EXPECT_TRUE(
- Matches("int i = 42; int j = (i %= 42);",
- BinaryOperator(HasOperatorName("%="))));
- EXPECT_TRUE(
- Matches("bool b = 42 &23;", BinaryOperator(HasOperatorName("&"))));
- EXPECT_TRUE(
- Matches("bool b = true && false;",
- BinaryOperator(HasOperatorName("&&"))));
- EXPECT_TRUE(
- Matches("bool b = true; bool c = (b &= false);",
- BinaryOperator(HasOperatorName("&="))));
- EXPECT_TRUE(
- Matches("bool b = 42 | 23;", BinaryOperator(HasOperatorName("|"))));
- EXPECT_TRUE(
- Matches("bool b = true || false;",
- BinaryOperator(HasOperatorName("||"))));
- EXPECT_TRUE(
- Matches("bool b = true; bool c = (b |= false);",
- BinaryOperator(HasOperatorName("|="))));
- EXPECT_TRUE(
- Matches("int i = 42 *23;", BinaryOperator(HasOperatorName("*"))));
- EXPECT_TRUE(
- Matches("int i = 42; int j = (i *= 23);",
- BinaryOperator(HasOperatorName("*="))));
- EXPECT_TRUE(
- Matches("int i = 42 / 23;", BinaryOperator(HasOperatorName("/"))));
- EXPECT_TRUE(
- Matches("int i = 42; int j = (i /= 23);",
- BinaryOperator(HasOperatorName("/="))));
- EXPECT_TRUE(
- Matches("int i = 42 + 23;", BinaryOperator(HasOperatorName("+"))));
- EXPECT_TRUE(
- Matches("int i = 42; int j = (i += 23);",
- BinaryOperator(HasOperatorName("+="))));
- EXPECT_TRUE(
- Matches("int i = 42 - 23;", BinaryOperator(HasOperatorName("-"))));
- EXPECT_TRUE(
- Matches("int i = 42; int j = (i -= 23);",
- BinaryOperator(HasOperatorName("-="))));
- EXPECT_TRUE(
- Matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
- BinaryOperator(HasOperatorName("->*"))));
- EXPECT_TRUE(
- Matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
- BinaryOperator(HasOperatorName(".*"))));
-
- // Member expressions as operators are not supported in matches.
- EXPECT_TRUE(
- NotMatches("struct A { void x(A *a) { a->x(this); } };",
- BinaryOperator(HasOperatorName("->"))));
-
- // Initializer assignments are not represented as operator equals.
- EXPECT_TRUE(
- NotMatches("bool b = true;", BinaryOperator(HasOperatorName("="))));
-
- // Array indexing is not represented as operator.
- EXPECT_TRUE(NotMatches("int a[42]; void x() { a[23]; }", UnaryOperator()));
-
- // Overloaded operators do not match at all.
- EXPECT_TRUE(NotMatches(
- "struct A { bool operator&&(const A &a) const { return false; } };"
- "void x() { A a, b; a && b; }",
- BinaryOperator()));
-}
-
-TEST(MatchUnaryOperator, HasOperatorName) {
- StatementMatcher OperatorNot = UnaryOperator(HasOperatorName("!"));
-
- EXPECT_TRUE(Matches("void x() { !true; } ", OperatorNot));
- EXPECT_TRUE(NotMatches("void x() { true; } ", OperatorNot));
-}
-
-TEST(MatchUnaryOperator, HasUnaryOperand) {
- StatementMatcher OperatorOnFalse =
- UnaryOperator(HasUnaryOperand(BoolLiteral(Equals(false))));
-
- EXPECT_TRUE(Matches("void x() { !false; }", OperatorOnFalse));
- EXPECT_TRUE(NotMatches("void x() { !true; }", OperatorOnFalse));
-}
-
-TEST(Matcher, UnaryOperatorTypes) {
- // Integration test that verifies the AST provides all unary operators in
- // a way we expect.
- EXPECT_TRUE(Matches("bool b = !true;", UnaryOperator(HasOperatorName("!"))));
- EXPECT_TRUE(
- Matches("bool b; bool *p = &b;", UnaryOperator(HasOperatorName("&"))));
- EXPECT_TRUE(Matches("int i = ~ 1;", UnaryOperator(HasOperatorName("~"))));
- EXPECT_TRUE(
- Matches("bool *p; bool b = *p;", UnaryOperator(HasOperatorName("*"))));
- EXPECT_TRUE(
- Matches("int i; int j = +i;", UnaryOperator(HasOperatorName("+"))));
- EXPECT_TRUE(
- Matches("int i; int j = -i;", UnaryOperator(HasOperatorName("-"))));
- EXPECT_TRUE(
- Matches("int i; int j = ++i;", UnaryOperator(HasOperatorName("++"))));
- EXPECT_TRUE(
- Matches("int i; int j = i++;", UnaryOperator(HasOperatorName("++"))));
- EXPECT_TRUE(
- Matches("int i; int j = --i;", UnaryOperator(HasOperatorName("--"))));
- EXPECT_TRUE(
- Matches("int i; int j = i--;", UnaryOperator(HasOperatorName("--"))));
-
- // We don't match conversion operators.
- EXPECT_TRUE(NotMatches("int i; double d = (double)i;", UnaryOperator()));
-
- // Function calls are not represented as operator.
- EXPECT_TRUE(NotMatches("void f(); void x() { f(); }", UnaryOperator()));
-
- // Overloaded operators do not match at all.
- // FIXME: We probably want to add that.
- EXPECT_TRUE(NotMatches(
- "struct A { bool operator!() const { return false; } };"
- "void x() { A a; !a; }", UnaryOperator(HasOperatorName("!"))));
-}
-
-TEST(Matcher, ConditionalOperator) {
- StatementMatcher Conditional = ConditionalOperator(
- HasCondition(BoolLiteral(Equals(true))),
- HasTrueExpression(BoolLiteral(Equals(false))));
-
- EXPECT_TRUE(Matches("void x() { true ? false : true; }", Conditional));
- EXPECT_TRUE(NotMatches("void x() { false ? false : true; }", Conditional));
- EXPECT_TRUE(NotMatches("void x() { true ? true : false; }", Conditional));
-
- StatementMatcher ConditionalFalse = ConditionalOperator(
- HasFalseExpression(BoolLiteral(Equals(false))));
-
- EXPECT_TRUE(Matches("void x() { true ? true : false; }", ConditionalFalse));
- EXPECT_TRUE(
- NotMatches("void x() { true ? false : true; }", ConditionalFalse));
-}
-
-TEST(Matcher, HasNameSupportsNamespaces) {
- EXPECT_TRUE(Matches("namespace a { namespace b { class C; } }",
- Class(HasName("a::b::C"))));
- EXPECT_TRUE(Matches("namespace a { namespace b { class C; } }",
- Class(HasName("::a::b::C"))));
- EXPECT_TRUE(Matches("namespace a { namespace b { class C; } }",
- Class(HasName("b::C"))));
- EXPECT_TRUE(Matches("namespace a { namespace b { class C; } }",
- Class(HasName("C"))));
- EXPECT_TRUE(NotMatches("namespace a { namespace b { class C; } }",
- Class(HasName("c::b::C"))));
- EXPECT_TRUE(NotMatches("namespace a { namespace b { class C; } }",
- Class(HasName("a::c::C"))));
- EXPECT_TRUE(NotMatches("namespace a { namespace b { class C; } }",
- Class(HasName("a::b::A"))));
- EXPECT_TRUE(NotMatches("namespace a { namespace b { class C; } }",
- Class(HasName("::C"))));
- EXPECT_TRUE(NotMatches("namespace a { namespace b { class C; } }",
- Class(HasName("::b::C"))));
- EXPECT_TRUE(NotMatches("namespace a { namespace b { class C; } }",
- Class(HasName("z::a::b::C"))));
- EXPECT_TRUE(NotMatches("namespace a { namespace b { class C; } }",
- Class(HasName("a+b::C"))));
- EXPECT_TRUE(NotMatches("namespace a { namespace b { class AC; } }",
- Class(HasName("C"))));
-}
-
-TEST(Matcher, HasNameSupportsOuterClasses) {
- EXPECT_TRUE(
- Matches("class A { class B { class C; }; };", Class(HasName("A::B::C"))));
- EXPECT_TRUE(
- Matches("class A { class B { class C; }; };",
- Class(HasName("::A::B::C"))));
- EXPECT_TRUE(
- Matches("class A { class B { class C; }; };", Class(HasName("B::C"))));
- EXPECT_TRUE(
- Matches("class A { class B { class C; }; };", Class(HasName("C"))));
- EXPECT_TRUE(
- NotMatches("class A { class B { class C; }; };",
- Class(HasName("c::B::C"))));
- EXPECT_TRUE(
- NotMatches("class A { class B { class C; }; };",
- Class(HasName("A::c::C"))));
- EXPECT_TRUE(
- NotMatches("class A { class B { class C; }; };",
- Class(HasName("A::B::A"))));
- EXPECT_TRUE(
- NotMatches("class A { class B { class C; }; };", Class(HasName("::C"))));
- EXPECT_TRUE(
- NotMatches("class A { class B { class C; }; };",
- Class(HasName("::B::C"))));
- EXPECT_TRUE(NotMatches("class A { class B { class C; }; };",
- Class(HasName("z::A::B::C"))));
- EXPECT_TRUE(
- NotMatches("class A { class B { class C; }; };",
- Class(HasName("A+B::C"))));
-}
-
-TEST(Matcher, IsDefinition) {
- DeclarationMatcher DefinitionOfClassA =
- Class(HasName("A"), IsDefinition());
- EXPECT_TRUE(Matches("class A {};", DefinitionOfClassA));
- EXPECT_TRUE(NotMatches("class A;", DefinitionOfClassA));
-
- DeclarationMatcher DefinitionOfVariableA =
- Variable(HasName("a"), IsDefinition());
- EXPECT_TRUE(Matches("int a;", DefinitionOfVariableA));
- EXPECT_TRUE(NotMatches("extern int a;", DefinitionOfVariableA));
-
- DeclarationMatcher DefinitionOfMethodA =
- Method(HasName("a"), IsDefinition());
- EXPECT_TRUE(Matches("class A { void a() {} };", DefinitionOfMethodA));
- EXPECT_TRUE(NotMatches("class A { void a(); };", DefinitionOfMethodA));
-}
-
-TEST(Matcher, OfClass) {
- StatementMatcher Constructor = ConstructorCall(HasDeclaration(Method(
- OfClass(HasName("X")))));
-
- EXPECT_TRUE(
- Matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
- EXPECT_TRUE(
- Matches("class X { public: X(); }; void x(int) { X x = X(); }",
- Constructor));
- EXPECT_TRUE(
- NotMatches("class Y { public: Y(); }; void x(int) { Y y; }",
- Constructor));
-}
-
-TEST(Matcher, VisitsTemplateInstantiations) {
- EXPECT_TRUE(Matches(
- "class A { public: void x(); };"
- "template <typename T> class B { public: void y() { T t; t.x(); } };"
- "void f() { B<A> b; b.y(); }", Call(Callee(Method(HasName("x"))))));
-
- EXPECT_TRUE(Matches(
- "class A { public: void x(); };"
- "class C {"
- " public:"
- " template <typename T> class B { public: void y() { T t; t.x(); } };"
- "};"
- "void f() {"
- " C::B<A> b; b.y();"
- "}", Class(HasName("C"),
- HasDescendant(Call(Callee(Method(HasName("x"))))))));
-}
-
-// For testing AST_MATCHER_P().
-AST_MATCHER_P(clang::Decl, Just, Matcher<clang::Decl>, AMatcher) {
- // Make sure all special variables are used: node, match_finder,
- // bound_nodes_builder, and the parameter named 'AMatcher'.
- return AMatcher.Matches(Node, Finder, Builder);
-}
-
-TEST(AstMatcherPMacro, Works) {
- DeclarationMatcher HasClassB = Just(Has(Id("b", Class(HasName("B")))));
-
- EXPECT_TRUE(MatchAndVerifyResultTrue("class A { class B {}; };",
- HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("b")));
-
- EXPECT_TRUE(MatchAndVerifyResultFalse("class A { class B {}; };",
- HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("a")));
-
- EXPECT_TRUE(MatchAndVerifyResultFalse("class A { class C {}; };",
- HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("b")));
-}
-
-AST_POLYMORPHIC_MATCHER_P(
- PolymorphicHas, Matcher<clang::Decl>, AMatcher) {
- COMPILE_ASSERT((llvm::is_same<NodeType, clang::Decl>::value) ||
- (llvm::is_same<NodeType, clang::Stmt>::value),
- assert_node_type_is_accessible);
- TypedBaseMatcher<clang::Decl> ChildMatcher(AMatcher);
- return Finder->MatchesChildOf(
- Node, ChildMatcher, Builder,
- ASTMatchFinder::kIgnoreImplicitCastsAndParentheses);
-}
-
-TEST(AstPolymorphicMatcherPMacro, Works) {
- DeclarationMatcher HasClassB = PolymorphicHas(Id("b", Class(HasName("B"))));
-
- EXPECT_TRUE(MatchAndVerifyResultTrue("class A { class B {}; };",
- HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("b")));
-
- EXPECT_TRUE(MatchAndVerifyResultFalse("class A { class B {}; };",
- HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("a")));
-
- EXPECT_TRUE(MatchAndVerifyResultFalse("class A { class C {}; };",
- HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("b")));
-
- StatementMatcher StatementHasClassB =
- PolymorphicHas(Class(HasName("B")));
-
- EXPECT_TRUE(Matches("void x() { class B {}; }", StatementHasClassB));
-}
-
-TEST(For, FindsForLoops) {
- EXPECT_TRUE(Matches("void f() { for(;;); }", For()));
- EXPECT_TRUE(Matches("void f() { if(true) for(;;); }", For()));
-}
-
-TEST(For, ReportsNoFalsePositives) {
- EXPECT_TRUE(NotMatches("void f() { ; }", For()));
- EXPECT_TRUE(NotMatches("void f() { if(true); }", For()));
-}
-
-TEST(CompoundStatement, HandlesSimpleCases) {
- EXPECT_TRUE(NotMatches("void f();", CompoundStatement()));
- EXPECT_TRUE(Matches("void f() {}", CompoundStatement()));
- EXPECT_TRUE(Matches("void f() {{}}", CompoundStatement()));
-}
-
-TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
- // It's not a compound statement just because there's "{}" in the source
- // text. This is an AST search, not grep.
- EXPECT_TRUE(NotMatches("namespace n { struct S {}; }",
- CompoundStatement()));
- EXPECT_TRUE(Matches("namespace n { struct S { void f() {{}} }; }",
- CompoundStatement()));
-}
-
-TEST(HasBody, FindsBodyOfForLoop) {
- StatementMatcher HasCompoundStatementBody =
- For(HasBody(CompoundStatement()));
- EXPECT_TRUE(Matches("void f() { for(;;) {} }",
- HasCompoundStatementBody));
- EXPECT_TRUE(NotMatches("void f() { for(;;); }",
- HasCompoundStatementBody));
-}
-
-TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
- // The simplest case: every compound statement is in a function
- // definition, and the function body itself must be a compound
- // statement.
- EXPECT_TRUE(Matches("void f() { for (;;); }",
- CompoundStatement(HasAnySubstatement(For()))));
-}
-
-TEST(HasAnySubstatement, IsNotRecursive) {
- // It's really "has any immediate substatement".
- EXPECT_TRUE(NotMatches("void f() { if (true) for (;;); }",
- CompoundStatement(HasAnySubstatement(For()))));
-}
-
-TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
- EXPECT_TRUE(Matches("void f() { if (true) { for (;;); } }",
- CompoundStatement(HasAnySubstatement(For()))));
-}
-
-TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
- EXPECT_TRUE(Matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
- CompoundStatement(HasAnySubstatement(For()))));
-}
-
-TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
- EXPECT_TRUE(Matches("void f() { }",
- CompoundStatement(StatementCountIs(0))));
- EXPECT_TRUE(NotMatches("void f() {}",
- CompoundStatement(StatementCountIs(1))));
-}
-
-TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
- EXPECT_TRUE(Matches("void f() { 1; }",
- CompoundStatement(StatementCountIs(1))));
- EXPECT_TRUE(NotMatches("void f() { 1; }",
- CompoundStatement(StatementCountIs(0))));
- EXPECT_TRUE(NotMatches("void f() { 1; }",
- CompoundStatement(StatementCountIs(2))));
-}
-
-TEST(StatementCountIs, WorksWithMultipleStatements) {
- EXPECT_TRUE(Matches("void f() { 1; 2; 3; }",
- CompoundStatement(StatementCountIs(3))));
-}
-
-TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
- EXPECT_TRUE(Matches("void f() { { 1; } { 1; 2; 3; 4; } }",
- CompoundStatement(StatementCountIs(1))));
- EXPECT_TRUE(Matches("void f() { { 1; } { 1; 2; 3; 4; } }",
- CompoundStatement(StatementCountIs(2))));
- EXPECT_TRUE(NotMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
- CompoundStatement(StatementCountIs(3))));
- EXPECT_TRUE(Matches("void f() { { 1; } { 1; 2; 3; 4; } }",
- CompoundStatement(StatementCountIs(4))));
-}
-
-} // end namespace tooling
-} // end namespace clang
diff --git a/unittests/Tooling/JsonCompileCommandLineDatabaseTest.cpp b/unittests/Tooling/JsonCompileCommandLineDatabaseTest.cpp
deleted file mode 100644
index 2a911d1063..0000000000
--- a/unittests/Tooling/JsonCompileCommandLineDatabaseTest.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-//===- unittest/Tooling/JsonCompileCommandLineDatabaseTest ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "../../lib/Tooling/JsonCompileCommandLineDatabase.h"
-#include "gtest/gtest.h"
-
-namespace clang {
-namespace tooling {
-
-TEST(UnescapeJsonCommandLine, ReturnsEmptyArrayOnEmptyString) {
- std::vector<std::string> Result = UnescapeJsonCommandLine("");
- EXPECT_TRUE(Result.empty());
-}
-
-TEST(UnescapeJsonCommandLine, SplitsOnSpaces) {
- std::vector<std::string> Result = UnescapeJsonCommandLine("a b c");
- ASSERT_EQ(3ul, Result.size());
- EXPECT_EQ("a", Result[0]);
- EXPECT_EQ("b", Result[1]);
- EXPECT_EQ("c", Result[2]);
-}
-
-TEST(UnescapeJsonCommandLine, MungesMultipleSpaces) {
- std::vector<std::string> Result = UnescapeJsonCommandLine(" a b ");
- ASSERT_EQ(2ul, Result.size());
- EXPECT_EQ("a", Result[0]);
- EXPECT_EQ("b", Result[1]);
-}
-
-TEST(UnescapeJsonCommandLine, UnescapesBackslashCharacters) {
- std::vector<std::string> Backslash = UnescapeJsonCommandLine("a\\\\\\\\");
- ASSERT_EQ(1ul, Backslash.size());
- EXPECT_EQ("a\\", Backslash[0]);
- std::vector<std::string> Quote = UnescapeJsonCommandLine("a\\\\\\\"");
- ASSERT_EQ(1ul, Quote.size());
- EXPECT_EQ("a\"", Quote[0]);
-}
-
-TEST(UnescapeJsonCommandLine, DoesNotMungeSpacesBetweenQuotes) {
- std::vector<std::string> Result = UnescapeJsonCommandLine("\\\" a b \\\"");
- ASSERT_EQ(1ul, Result.size());
- EXPECT_EQ(" a b ", Result[0]);
-}
-
-TEST(UnescapeJsonCommandLine, AllowsMultipleQuotedArguments) {
- std::vector<std::string> Result = UnescapeJsonCommandLine(
- " \\\" a \\\" \\\" b \\\" ");
- ASSERT_EQ(2ul, Result.size());
- EXPECT_EQ(" a ", Result[0]);
- EXPECT_EQ(" b ", Result[1]);
-}
-
-TEST(UnescapeJsonCommandLine, AllowsEmptyArgumentsInQuotes) {
- std::vector<std::string> Result = UnescapeJsonCommandLine(
- "\\\"\\\"\\\"\\\"");
- ASSERT_EQ(1ul, Result.size());
- EXPECT_TRUE(Result[0].empty()) << Result[0];
-}
-
-TEST(UnescapeJsonCommandLine, ParsesEscapedQuotesInQuotedStrings) {
- std::vector<std::string> Result = UnescapeJsonCommandLine(
- "\\\"\\\\\\\"\\\"");
- ASSERT_EQ(1ul, Result.size());
- EXPECT_EQ("\"", Result[0]);
-}
-
-TEST(UnescapeJsonCommandLine, ParsesMultipleArgumentsWithEscapedCharacters) {
- std::vector<std::string> Result = UnescapeJsonCommandLine(
- " \\\\\\\" \\\"a \\\\\\\" b \\\" \\\"and\\\\\\\\c\\\" \\\\\\\"");
- ASSERT_EQ(4ul, Result.size());
- EXPECT_EQ("\"", Result[0]);
- EXPECT_EQ("a \" b ", Result[1]);
- EXPECT_EQ("and\\c", Result[2]);
- EXPECT_EQ("\"", Result[3]);
-}
-
-TEST(UnescapeJsonCommandLine, ParsesStringsWithoutSpacesIntoSingleArgument) {
- std::vector<std::string> QuotedNoSpaces = UnescapeJsonCommandLine(
- "\\\"a\\\"\\\"b\\\"");
- ASSERT_EQ(1ul, QuotedNoSpaces.size());
- EXPECT_EQ("ab", QuotedNoSpaces[0]);
-
- std::vector<std::string> MixedNoSpaces = UnescapeJsonCommandLine(
- "\\\"a\\\"bcd\\\"ef\\\"\\\"\\\"\\\"g\\\"");
- ASSERT_EQ(1ul, MixedNoSpaces.size());
- EXPECT_EQ("abcdefg", MixedNoSpaces[0]);
-}
-
-TEST(UnescapeJsonCommandLine, ParsesQuotedStringWithoutClosingQuote) {
- std::vector<std::string> Unclosed = UnescapeJsonCommandLine("\"abc");
- ASSERT_EQ(1ul, Unclosed.size());
- EXPECT_EQ("abc", Unclosed[0]);
-
- std::vector<std::string> EndsInBackslash = UnescapeJsonCommandLine("\"a\\");
- ASSERT_EQ(1ul, EndsInBackslash.size());
- EXPECT_EQ("a", EndsInBackslash[0]);
-
- std::vector<std::string> Empty = UnescapeJsonCommandLine("\"");
- ASSERT_EQ(1ul, Empty.size());
- EXPECT_EQ("", Empty[0]);
-}
-
-TEST(JsonCompileCommandLineParser, FailsOnEmptyString) {
- JsonCompileCommandLineParser Parser("", NULL);
- EXPECT_FALSE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, DoesNotReadAfterInput) {
- JsonCompileCommandLineParser Parser(llvm::StringRef(NULL, 0), NULL);
- EXPECT_FALSE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, ParsesEmptyArray) {
- JsonCompileCommandLineParser Parser("[]", NULL);
- EXPECT_TRUE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, FailsIfNotClosingArray) {
- JsonCompileCommandLineParser JustOpening("[", NULL);
- EXPECT_FALSE(JustOpening.Parse()) << JustOpening.GetErrorMessage();
- JsonCompileCommandLineParser WithSpaces(" [ ", NULL);
- EXPECT_FALSE(WithSpaces.Parse()) << WithSpaces.GetErrorMessage();
- JsonCompileCommandLineParser WithGarbage(" [x", NULL);
- EXPECT_FALSE(WithGarbage.Parse()) << WithGarbage.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, ParsesEmptyArrayWithWhitespace) {
- JsonCompileCommandLineParser Spaces(" [ ] ", NULL);
- EXPECT_TRUE(Spaces.Parse()) << Spaces.GetErrorMessage();
- JsonCompileCommandLineParser AllWhites("\t\r\n[\t\n \t\r ]\t\r \n\n", NULL);
- EXPECT_TRUE(AllWhites.Parse()) << AllWhites.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, FailsIfNotStartingArray) {
- JsonCompileCommandLineParser ObjectStart("{", NULL);
- EXPECT_FALSE(ObjectStart.Parse()) << ObjectStart.GetErrorMessage();
- // We don't implement a full JSON parser, and thus parse only a subset
- // of valid JSON.
- JsonCompileCommandLineParser Object("{}", NULL);
- EXPECT_FALSE(Object.Parse()) << Object.GetErrorMessage();
- JsonCompileCommandLineParser Character("x", NULL);
- EXPECT_FALSE(Character.Parse()) << Character.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, ParsesEmptyObject) {
- JsonCompileCommandLineParser Parser("[{}]", NULL);
- EXPECT_TRUE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, ParsesObject) {
- JsonCompileCommandLineParser Parser("[{\"a\":\"/b\"}]", NULL);
- EXPECT_TRUE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, ParsesMultipleKeyValuePairsInObject) {
- JsonCompileCommandLineParser Parser(
- "[{\"a\":\"/b\",\"c\":\"d\",\"e\":\"f\"}]", NULL);
- EXPECT_TRUE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, FailsIfNotClosingObject) {
- JsonCompileCommandLineParser MissingCloseOnEmpty("[{]", NULL);
- EXPECT_FALSE(MissingCloseOnEmpty.Parse())
- << MissingCloseOnEmpty.GetErrorMessage();
- JsonCompileCommandLineParser MissingCloseAfterPair("[{\"a\":\"b\"]", NULL);
- EXPECT_FALSE(MissingCloseAfterPair.Parse())
- << MissingCloseAfterPair.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, FailsIfMissingColon) {
- JsonCompileCommandLineParser StringString("[{\"a\"\"/b\"}]", NULL);
- EXPECT_FALSE(StringString.Parse()) << StringString.GetErrorMessage();
- JsonCompileCommandLineParser StringSpaceString("[{\"a\" \"b\"}]", NULL);
- EXPECT_FALSE(StringSpaceString.Parse())
- << StringSpaceString.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, FailsOnMissingQuote) {
- JsonCompileCommandLineParser OpenQuote("[{a\":\"b\"}]", NULL);
- EXPECT_FALSE(OpenQuote.Parse()) << OpenQuote.GetErrorMessage();
- JsonCompileCommandLineParser CloseQuote("[{\"a\":\"b}]", NULL);
- EXPECT_FALSE(CloseQuote.Parse()) << CloseQuote.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, ParsesEscapedQuotes) {
- JsonCompileCommandLineParser Parser(
- "[{\"a\":\"\\\"b\\\" \\\" \\\"\"}]", NULL);
- EXPECT_TRUE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, ParsesEmptyString) {
- JsonCompileCommandLineParser Parser("[{\"a\":\"\"}]", NULL);
- EXPECT_TRUE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, FailsOnMissingString) {
- JsonCompileCommandLineParser MissingValue("[{\"a\":}]", NULL);
- EXPECT_FALSE(MissingValue.Parse()) << MissingValue.GetErrorMessage();
- JsonCompileCommandLineParser MissingKey("[{:\"b\"}]", NULL);
- EXPECT_FALSE(MissingKey.Parse()) << MissingKey.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, ParsesMultipleObjects) {
- JsonCompileCommandLineParser Parser(
- "["
- " { \"a\" : \"b\" },"
- " { \"a\" : \"b\" },"
- " { \"a\" : \"b\" }"
- "]", NULL);
- EXPECT_TRUE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, FailsOnMissingComma) {
- JsonCompileCommandLineParser Parser(
- "["
- " { \"a\" : \"b\" }"
- " { \"a\" : \"b\" }"
- "]", NULL);
- EXPECT_FALSE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, FailsOnSuperfluousComma) {
- JsonCompileCommandLineParser Parser(
- "[ { \"a\" : \"b\" }, ]", NULL);
- EXPECT_FALSE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-TEST(JsonCompileCommandLineParser, ParsesSpacesInBetweenTokens) {
- JsonCompileCommandLineParser Parser(
- " \t \n\n \r [ \t \n\n \r"
- " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
- " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r,\t \n\n \r"
- " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
- " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r]\t \n\n \r",
- NULL);
- EXPECT_TRUE(Parser.Parse()) << Parser.GetErrorMessage();
-}
-
-} // end namespace tooling
-} // end namespace clang
diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp
deleted file mode 100644
index 6e5bc6b613..0000000000
--- a/unittests/Tooling/ToolingTest.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-//===- unittest/Tooling/ToolingTest.cpp - Tooling unit tests --------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/Twine.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclGroup.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/Tooling/Tooling.h"
-#include "gtest/gtest.h"
-
-namespace clang {
-namespace tooling {
-
-namespace {
-/// Takes an ast consumer and returns it from CreateASTConsumer. This only
-/// works with single translation unit compilations.
-class TestAction : public clang::ASTFrontendAction {
- public:
- /// Takes ownership of TestConsumer.
- explicit TestAction(clang::ASTConsumer *TestConsumer)
- : TestConsumer(TestConsumer) {}
-
- protected:
- virtual clang::ASTConsumer* CreateASTConsumer(
- clang::CompilerInstance& compiler, llvm::StringRef dummy) {
- /// TestConsumer will be deleted by the framework calling us.
- return TestConsumer;
- }
-
- private:
- clang::ASTConsumer * const TestConsumer;
-};
-
-class FindTopLevelDeclConsumer : public clang::ASTConsumer {
- public:
- explicit FindTopLevelDeclConsumer(bool *FoundTopLevelDecl)
- : FoundTopLevelDecl(FoundTopLevelDecl) {}
- virtual void HandleTopLevelDecl(clang::DeclGroupRef DeclGroup) {
- *FoundTopLevelDecl = true;
- }
- private:
- bool * const FoundTopLevelDecl;
-};
-} // end namespace
-
-TEST(RunSyntaxOnlyToolOnCode, FindsTopLevelDeclOnEmptyCode) {
- bool FoundTopLevelDecl = false;
- EXPECT_TRUE(RunSyntaxOnlyToolOnCode(
- new TestAction(new FindTopLevelDeclConsumer(&FoundTopLevelDecl)), ""));
- EXPECT_TRUE(FoundTopLevelDecl);
-}
-
-namespace {
-class FindClassDeclXConsumer : public clang::ASTConsumer {
- public:
- FindClassDeclXConsumer(bool *FoundClassDeclX)
- : FoundClassDeclX(FoundClassDeclX) {}
- virtual void HandleTopLevelDecl(clang::DeclGroupRef GroupRef) {
- if (CXXRecordDecl* Record = llvm::dyn_cast<clang::CXXRecordDecl>(
- *GroupRef.begin())) {
- if (Record->getName() == "X") {
- *FoundClassDeclX = true;
- }
- }
- }
- private:
- bool *FoundClassDeclX;
-};
-} // end namespace
-
-TEST(RunSyntaxOnlyToolOnCode, FindsClassDecl) {
- bool FoundClassDeclX = false;
- EXPECT_TRUE(RunSyntaxOnlyToolOnCode(new TestAction(
- new FindClassDeclXConsumer(&FoundClassDeclX)), "class X;"));
- EXPECT_TRUE(FoundClassDeclX);
-
- FoundClassDeclX = false;
- EXPECT_TRUE(RunSyntaxOnlyToolOnCode(new TestAction(
- new FindClassDeclXConsumer(&FoundClassDeclX)), "class Y;"));
- EXPECT_FALSE(FoundClassDeclX);
-}
-
-TEST(FindCompileArgsInJsonDatabase, FindsNothingIfEmpty) {
- std::string ErrorMessage;
- CompileCommand NotFound = FindCompileArgsInJsonDatabase(
- "a-file.cpp", "", ErrorMessage);
- EXPECT_TRUE(NotFound.CommandLine.empty()) << ErrorMessage;
- EXPECT_TRUE(NotFound.Directory.empty()) << ErrorMessage;
-}
-
-TEST(FindCompileArgsInJsonDatabase, ReadsSingleEntry) {
- llvm::StringRef Directory("/some/directory");
- llvm::StringRef FileName("/path/to/a-file.cpp");
- llvm::StringRef Command("/path/to/compiler and some arguments");
- std::string ErrorMessage;
- CompileCommand FoundCommand = FindCompileArgsInJsonDatabase(
- FileName,
- (llvm::Twine("[{\"directory\":\"") + Directory + "\"," +
- "\"command\":\"" + Command + "\","
- "\"file\":\"" + FileName + "\"}]").str(), ErrorMessage);
- EXPECT_EQ(Directory, FoundCommand.Directory) << ErrorMessage;
- ASSERT_EQ(4u, FoundCommand.CommandLine.size()) << ErrorMessage;
- EXPECT_EQ("/path/to/compiler", FoundCommand.CommandLine[0]) << ErrorMessage;
- EXPECT_EQ("and", FoundCommand.CommandLine[1]) << ErrorMessage;
- EXPECT_EQ("some", FoundCommand.CommandLine[2]) << ErrorMessage;
- EXPECT_EQ("arguments", FoundCommand.CommandLine[3]) << ErrorMessage;
-
- CompileCommand NotFound = FindCompileArgsInJsonDatabase(
- "a-file.cpp",
- (llvm::Twine("[{\"directory\":\"") + Directory + "\"," +
- "\"command\":\"" + Command + "\","
- "\"file\":\"" + FileName + "\"}]").str(), ErrorMessage);
- EXPECT_TRUE(NotFound.Directory.empty()) << ErrorMessage;
- EXPECT_TRUE(NotFound.CommandLine.empty()) << ErrorMessage;
-}
-
-TEST(FindCompileArgsInJsonDatabase, ReadsCompileCommandLinesWithSpaces) {
- llvm::StringRef Directory("/some/directory");
- llvm::StringRef FileName("/path/to/a-file.cpp");
- llvm::StringRef Command("\\\"/path to compiler\\\" \\\"and an argument\\\"");
- std::string ErrorMessage;
- CompileCommand FoundCommand = FindCompileArgsInJsonDatabase(
- FileName,
- (llvm::Twine("[{\"directory\":\"") + Directory + "\"," +
- "\"command\":\"" + Command + "\","
- "\"file\":\"" + FileName + "\"}]").str(), ErrorMessage);
- ASSERT_EQ(2u, FoundCommand.CommandLine.size());
- EXPECT_EQ("/path to compiler", FoundCommand.CommandLine[0]) << ErrorMessage;
- EXPECT_EQ("and an argument", FoundCommand.CommandLine[1]) << ErrorMessage;
-}
-
-TEST(FindCompileArgsInJsonDatabase, ReadsDirectoryWithSpaces) {
- llvm::StringRef Directory("/some directory / with spaces");
- llvm::StringRef FileName("/path/to/a-file.cpp");
- llvm::StringRef Command("a command");
- std::string ErrorMessage;
- CompileCommand FoundCommand = FindCompileArgsInJsonDatabase(
- FileName,
- (llvm::Twine("[{\"directory\":\"") + Directory + "\"," +
- "\"command\":\"" + Command + "\","
- "\"file\":\"" + FileName + "\"}]").str(), ErrorMessage);
- EXPECT_EQ(Directory, FoundCommand.Directory) << ErrorMessage;
-}
-
-TEST(FindCompileArgsInJsonDatabase, FindsEntry) {
- llvm::StringRef Directory("directory");
- llvm::StringRef FileName("file");
- llvm::StringRef Command("command");
- std::string JsonDatabase = "[";
- for (int I = 0; I < 10; ++I) {
- if (I > 0) JsonDatabase += ",";
- JsonDatabase += (llvm::Twine(
- "{\"directory\":\"") + Directory + llvm::Twine(I) + "\"," +
- "\"command\":\"" + Command + llvm::Twine(I) + "\","
- "\"file\":\"" + FileName + llvm::Twine(I) + "\"}").str();
- }
- JsonDatabase += "]";
- std::string ErrorMessage;
- CompileCommand FoundCommand = FindCompileArgsInJsonDatabase(
- "file4", JsonDatabase, ErrorMessage);
- EXPECT_EQ("directory4", FoundCommand.Directory) << ErrorMessage;
- ASSERT_EQ(1u, FoundCommand.CommandLine.size()) << ErrorMessage;
- EXPECT_EQ("command4", FoundCommand.CommandLine[0]) << ErrorMessage;
-}
-
-} // end namespace tooling
-} // end namespace clang
-