First revision of the dynamic ASTMatcher library.

This library supports all the features of the compile-time based ASTMatcher
library, but allows the user to specify and construct the matchers at runtime.
It contains the following modules:
 - A variant type, to be used by the matcher factory.
 - A registry, where the matchers are indexed by name and have a factory method
   with a generic signature.
 - A simple matcher expression parser, that can be used to convert a matcher
   expression string into actual matchers that can be used with the AST at
   runtime.

Many features where omitted from this first revision to simplify this code
review. The main ideas are still represented in this change and it already has
support working use cases.
Things that are missing:
 - Support for polymorphic matchers. These requires supporting code in the
   registry, the marshallers and the variant type.
 - Support for numbers, char and bool arguments to the matchers. This requires
   supporting code in the parser and the variant type.
 - A command line program putting everything together and providing an already
   functional tool.

Patch by Samuel Benzaquen.

llvm-svn: 181768
diff --git a/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt b/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt
new file mode 100644
index 0000000..ba920a4
--- /dev/null
+++ b/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangDynamicASTMatchers
+  Diagnostics.cpp
+  VariantValue.cpp
+  Parser.cpp
+  Registry.cpp
+  )
+
+add_dependencies(clangDynamicASTMatchers
+  clangASTMatchers
+  )
diff --git a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
new file mode 100644
index 0000000..fb3cac3
--- /dev/null
+++ b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
@@ -0,0 +1,113 @@
+//===--- Diagnostics.cpp - Helper class for error diagnostics -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+Diagnostics::ArgStream &
+Diagnostics::ArgStream::operator<<(const Twine &Arg) {
+  Out->push_back(Arg.str());
+  return *this;
+}
+
+Diagnostics::ArgStream Diagnostics::pushErrorFrame(const SourceRange &Range,
+                                                   ErrorType Error) {
+  Frames.insert(Frames.begin(), ErrorFrame());
+  ErrorFrame &Last = Frames.front();
+  Last.Range = Range;
+  Last.Type = Error;
+  ArgStream Out = { &Last.Args };
+  return Out;
+}
+
+StringRef ErrorTypeToString(Diagnostics::ErrorType Type) {
+  switch (Type) {
+  case Diagnostics::ET_RegistryNotFound:
+    return "Matcher not found: $0";
+  case Diagnostics::ET_RegistryWrongArgCount:
+    return "Incorrect argument count. (Expected = $0) != (Actual = $1)";
+  case Diagnostics::ET_RegistryWrongArgType:
+    return "Incorrect type on function $0 for arg $1.";
+
+  case Diagnostics::ET_ParserStringError:
+    return "Error parsing string token: <$0>";
+  case Diagnostics::ET_ParserMatcherArgFailure:
+    return "Error parsing argument $0 for matcher $1.";
+  case Diagnostics::ET_ParserMatcherFailure:
+    return "Error building matcher $0.";
+  case Diagnostics::ET_ParserNoOpenParen:
+    return "Error parsing matcher. Found token <$0> while looking for '('.";
+  case Diagnostics::ET_ParserNoCloseParen:
+    return "Error parsing matcher. Found end-of-code while looking for ')'.";
+  case Diagnostics::ET_ParserNoComma:
+    return "Error parsing matcher. Found token <$0> while looking for ','.";
+  case Diagnostics::ET_ParserNoCode:
+    return "End of code found while looking for token.";
+  case Diagnostics::ET_ParserNotAMatcher:
+    return "Input value is not a matcher expression.";
+  case Diagnostics::ET_ParserInvalidToken:
+    return "Invalid token <$0> found when looking for a value.";
+
+  case Diagnostics::ET_None:
+    return "<N/A>";
+  }
+  llvm_unreachable("Unknown ErrorType value.");
+}
+
+std::string FormatErrorString(StringRef FormatString,
+                              ArrayRef<std::string> Args) {
+  std::string Out;
+  while (!FormatString.empty()) {
+    std::pair<StringRef, StringRef> Pieces = FormatString.split("$");
+    Out += Pieces.first.str();
+    if (Pieces.second.empty()) break;
+
+    const char Next = Pieces.second.front();
+    FormatString = Pieces.second.drop_front();
+    if (Next >= '0' && Next <= '9') {
+      const unsigned Index = Next - '0';
+      if (Index < Args.size()) {
+        Out += Args[Index];
+      } else {
+        Out += "<Argument_Not_Provided>";
+      }
+    }
+  }
+  return Out;
+}
+
+std::string Diagnostics::ErrorFrame::ToString() const {
+  StringRef FormatString = ErrorTypeToString(Type);
+  std::string ErrorOut = FormatErrorString(FormatString, Args);
+  if (Range.Start.Line > 0 && Range.Start.Column > 0)
+    return (Twine(Range.Start.Line) + ":" + Twine(Range.Start.Column) + ": " +
+            ErrorOut).str();
+  return ErrorOut;
+}
+
+std::string Diagnostics::ToString() const {
+  if (Frames.empty()) return "";
+  return Frames[Frames.size() - 1].ToString();
+}
+
+std::string Diagnostics::ToStringFull() const {
+  std::string Result;
+  for (size_t i = 0, end = Frames.size(); i != end; ++i) {
+    if (i > 0) Result += "\n";
+    Result += Frames[i].ToString();
+  }
+  return Result;
+}
+
+}  // namespace dynamic
+}  // namespace ast_matchers
+}  // namespace clang
diff --git a/clang/lib/ASTMatchers/Dynamic/Makefile b/clang/lib/ASTMatchers/Dynamic/Makefile
new file mode 100644
index 0000000..a57d752
--- /dev/null
+++ b/clang/lib/ASTMatchers/Dynamic/Makefile
@@ -0,0 +1,13 @@
+##===- clang/lib/ASTMatchers/Dynamic/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 := clangDynamicASTMatchers
+
+include $(CLANG_LEVEL)/Makefile
diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
new file mode 100644
index 0000000..e75a175
--- /dev/null
+++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -0,0 +1,223 @@
+//===--- Marshallers.h - Generic matcher function marshallers -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Functions templates and classes to wrap matcher construct functions.
+///
+/// A collection of template function and classes that provide a generic
+/// marshalling layer on top of matcher construct functions.
+/// These are used by the registry to export all marshaller constructors with
+/// the same generic interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
+#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
+
+#include <list>
+#include <string>
+#include <vector>
+
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
+#include "clang/ASTMatchers/Dynamic/VariantValue.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/type_traits.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+namespace internal {
+
+/// \brief Helper template class to just from argument type to the right is/get
+///   functions in VariantValue.
+/// Used to verify and extract the matcher arguments below.
+template <class T> struct ArgTypeTraits;
+template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
+};
+
+template <> struct ArgTypeTraits<std::string> {
+  static bool is(const VariantValue &Value) { return Value.isString(); }
+  static const std::string &get(const VariantValue &Value) {
+    return Value.getString();
+  }
+};
+
+template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
+  static bool is(const VariantValue &Value) { return Value.isMatcher(); }
+  static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
+    return Value.getTypedMatcher<T>();
+  }
+
+};
+
+/// \brief Generic MatcherCreate interface.
+///
+/// Provides a \c run() method that constructs the matcher from the provided
+/// arguments.
+class MatcherCreateCallback {
+public:
+  virtual ~MatcherCreateCallback() {}
+  virtual DynTypedMatcher *run(const SourceRange &NameRange,
+                               ArrayRef<ParserValue> Args,
+                               Diagnostics *Error) const = 0;
+};
+
+/// \brief Simple callback implementation. Marshaller and function are provided.
+///
+/// \param Marshaller Function to unpack the arguments and call \c Func
+/// \param Func Matcher construct function. This is the function that
+///   compile-time matcher expressions would use to create the matcher.
+template <typename MarshallerType, typename FuncType>
+class FixedArgCountMatcherCreateCallback : public MatcherCreateCallback {
+public:
+  FixedArgCountMatcherCreateCallback(MarshallerType Marshaller, FuncType Func,
+                                     StringRef MatcherName)
+      : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName.str()) {}
+
+  DynTypedMatcher *run(const SourceRange &NameRange,
+                       ArrayRef<ParserValue> Args, Diagnostics *Error) const {
+    return Marshaller(Func, MatcherName, NameRange, Args, Error);
+  }
+
+private:
+  const MarshallerType Marshaller;
+  const FuncType Func;
+  const std::string MatcherName;
+};
+
+/// \brief Helper function to do template argument deduction.
+template <typename MarshallerType, typename FuncType>
+MatcherCreateCallback *
+createMarshallerCallback(MarshallerType Marshaller, FuncType Func,
+                         StringRef MatcherName) {
+  return new FixedArgCountMatcherCreateCallback<MarshallerType, FuncType>(
+      Marshaller, Func, MatcherName);
+}
+
+/// \brief Helper macros to check the arguments on all marshaller functions.
+#define CHECK_ARG_COUNT(count)                                                 \
+  if (Args.size() != count) {                                                  \
+    Error->pushErrorFrame(NameRange, Error->ET_RegistryWrongArgCount)          \
+        << count << Args.size();                                               \
+    return NULL;                                                               \
+  }
+
+#define CHECK_ARG_TYPE(index, type)                                            \
+  if (!ArgTypeTraits<type>::is(Args[index].Value)) {                           \
+    Error->pushErrorFrame(Args[index].Range, Error->ET_RegistryWrongArgType)   \
+        << MatcherName << (index + 1);                                         \
+    return NULL;                                                               \
+  }
+
+/// \brief Metafunction to normalize argument types.
+///
+/// We need to remove the const& out of the function parameters to be able to
+/// find values on VariantValue.
+template <typename T>
+struct remove_const_ref :
+    public llvm::remove_const<typename llvm::remove_reference<T>::type> {
+};
+
+/// \brief 0-arg marshaller function.
+template <typename ReturnType>
+DynTypedMatcher *matcherMarshall0(ReturnType (*Func)(), StringRef MatcherName,
+                                  const SourceRange &NameRange,
+                                  ArrayRef<ParserValue> Args,
+                                  Diagnostics *Error) {
+  CHECK_ARG_COUNT(0);
+  return Func().clone();
+}
+
+/// \brief 1-arg marshaller function.
+template <typename ReturnType, typename InArgType1>
+DynTypedMatcher *matcherMarshall1(ReturnType (*Func)(InArgType1),
+                                  StringRef MatcherName,
+                                  const SourceRange &NameRange,
+                                  ArrayRef<ParserValue> Args,
+                                  Diagnostics *Error) {
+  typedef typename remove_const_ref<InArgType1>::type ArgType1;
+  CHECK_ARG_COUNT(1);
+  CHECK_ARG_TYPE(0, ArgType1);
+  return Func(ArgTypeTraits<ArgType1>::get(Args[0].Value)).clone();
+}
+
+/// \brief Variadic marshaller function.
+template <typename BaseType, typename DerivedType>
+class VariadicMatcherCreateCallback : public MatcherCreateCallback {
+public:
+  explicit VariadicMatcherCreateCallback(StringRef MatcherName)
+      : MatcherName(MatcherName.str()) {}
+
+  typedef ast_matchers::internal::Matcher<DerivedType> DerivedMatcherType;
+
+  DynTypedMatcher *run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
+                       Diagnostics *Error) const {
+    std::list<DerivedMatcherType> References;
+    std::vector<const DerivedMatcherType *> InnerArgs(Args.size());
+    for (size_t i = 0, e = Args.size(); i != e; ++i) {
+      CHECK_ARG_TYPE(i, DerivedMatcherType);
+      References.push_back(
+          ArgTypeTraits<DerivedMatcherType>::get(Args[i].Value));
+      InnerArgs[i] = &References.back();
+    }
+    return ast_matchers::internal::makeDynCastAllOfComposite<BaseType>(
+        ArrayRef<const DerivedMatcherType *>(InnerArgs)).clone();
+  }
+
+private:
+  const std::string MatcherName;
+};
+
+#undef CHECK_ARG_COUNT
+#undef CHECK_ARG_TYPE
+
+/// Helper functions to select the appropriate marshaller functions.
+/// They detects the number of arguments, arguments types and return type.
+
+/// \brief 0-arg overload
+template <typename ReturnType>
+MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(),
+                                               StringRef MatcherName) {
+  return createMarshallerCallback(matcherMarshall0<ReturnType>, Func,
+                                  MatcherName);
+}
+
+/// \brief 1-arg overload
+template <typename ReturnType, typename ArgType1>
+MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1),
+                                               StringRef MatcherName) {
+  return createMarshallerCallback(matcherMarshall1<ReturnType, ArgType1>, Func,
+                                  MatcherName);
+}
+
+/// \brief Variadic overload.
+template <typename MatcherType>
+MatcherCreateCallback *makeMatcherAutoMarshall(
+    ast_matchers::internal::VariadicAllOfMatcher<MatcherType> Func,
+    StringRef MatcherName) {
+  return new VariadicMatcherCreateCallback<MatcherType, MatcherType>(
+      MatcherName);
+}
+
+template <typename BaseType, typename MatcherType>
+MatcherCreateCallback *
+makeMatcherAutoMarshall(ast_matchers::internal::VariadicDynCastAllOfMatcher<
+                            BaseType, MatcherType> Func,
+                        StringRef MatcherName) {
+  return new VariadicMatcherCreateCallback<BaseType, MatcherType>(MatcherName);
+}
+
+}  // namespace internal
+}  // namespace dynamic
+}  // namespace ast_matchers
+}  // namespace clang
+
+#endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
diff --git a/clang/lib/ASTMatchers/Dynamic/Parser.cpp b/clang/lib/ASTMatchers/Dynamic/Parser.cpp
new file mode 100644
index 0000000..1678820
--- /dev/null
+++ b/clang/lib/ASTMatchers/Dynamic/Parser.cpp
@@ -0,0 +1,332 @@
+//===--- Parser.cpp - Matcher expression parser -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Recursive parser implementation for the matcher expression grammar.
+///
+//===----------------------------------------------------------------------===//
+
+#include <string>
+#include <vector>
+
+#include "clang/ASTMatchers/Dynamic/Parser.h"
+#include "clang/ASTMatchers/Dynamic/Registry.h"
+#include "clang/Basic/CharInfo.h"
+#include "llvm/ADT/Twine.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+/// \brief Simple structure to hold information for one token from the parser.
+struct Parser::TokenInfo {
+  /// \brief Different possible tokens.
+  enum TokenKind {
+    TK_Eof = 0,
+    TK_OpenParen = 1,
+    TK_CloseParen = 2,
+    TK_Comma = 3,
+    TK_Literal = 4,
+    TK_Ident = 5,
+    TK_InvalidChar = 6,
+    TK_Error = 7
+  };
+
+  TokenInfo() : Text(), Kind(TK_Eof), Range(), Value() {}
+
+  StringRef Text;
+  TokenKind Kind;
+  SourceRange Range;
+  VariantValue Value;
+};
+
+/// \brief Simple tokenizer for the parser.
+class Parser::CodeTokenizer {
+public:
+  explicit CodeTokenizer(StringRef MatcherCode, Diagnostics *Error)
+      : Code(MatcherCode), StartOfLine(MatcherCode), Line(1), Error(Error) {
+    NextToken = getNextToken();
+  }
+
+  /// \brief Returns but doesn't consume the next token.
+  const TokenInfo &peekNextToken() const { return NextToken; }
+
+  /// \brief Consumes and returns the next token.
+  TokenInfo consumeNextToken() {
+    TokenInfo ThisToken = NextToken;
+    NextToken = getNextToken();
+    return ThisToken;
+  }
+
+  TokenInfo::TokenKind nextTokenKind() const { return NextToken.Kind; }
+
+private:
+  TokenInfo getNextToken() {
+    consumeWhitespace();
+    TokenInfo Result;
+    Result.Range.Start = currentLocation();
+
+    if (Code.empty()) {
+      Result.Kind = TokenInfo::TK_Eof;
+      Result.Text = "";
+      return Result;
+    }
+
+    switch (Code[0]) {
+    case ',':
+      Result.Kind = TokenInfo::TK_Comma;
+      Result.Text = Code.substr(0, 1);
+      Code = Code.drop_front();
+      break;
+    case '(':
+      Result.Kind = TokenInfo::TK_OpenParen;
+      Result.Text = Code.substr(0, 1);
+      Code = Code.drop_front();
+      break;
+    case ')':
+      Result.Kind = TokenInfo::TK_CloseParen;
+      Result.Text = Code.substr(0, 1);
+      Code = Code.drop_front();
+      break;
+
+    case '"':
+    case '\'':
+      // Parse a string literal.
+      consumeStringLiteral(&Result);
+      break;
+
+    default:
+      if (isAlphanumeric(Code[0])) {
+        // Parse an identifier
+        size_t TokenLength = 1;
+        while (TokenLength < Code.size() && isAlphanumeric(Code[TokenLength]))
+          ++TokenLength;
+        Result.Kind = TokenInfo::TK_Ident;
+        Result.Text = Code.substr(0, TokenLength);
+        Code = Code.drop_front(TokenLength);
+      } else {
+        Result.Kind = TokenInfo::TK_InvalidChar;
+        Result.Text = Code.substr(0, 1);
+        Code = Code.drop_front(1);
+      }
+      break;
+    }
+
+    Result.Range.End = currentLocation();
+    return Result;
+  }
+
+  /// \brief Consume a string literal.
+  ///
+  /// \c Code must be positioned at the start of the literal (the opening
+  /// quote). Consumed until it finds the same closing quote character.
+  void consumeStringLiteral(TokenInfo *Result) {
+    bool InEscape = false;
+    const char Marker = Code[0];
+    for (size_t Length = 1, Size = Code.size(); Length != Size; ++Length) {
+      if (InEscape) {
+        InEscape = false;
+        continue;
+      }
+      if (Code[Length] == '\\') {
+        InEscape = true;
+        continue;
+      }
+      if (Code[Length] == Marker) {
+        Result->Kind = TokenInfo::TK_Literal;
+        Result->Text = Code.substr(0, Length + 1);
+        Result->Value = Code.substr(1, Length - 1).str();
+        Code = Code.drop_front(Length + 1);
+        return;
+      }
+    }
+
+    StringRef ErrorText = Code;
+    Code = Code.drop_front(Code.size());
+    SourceRange Range;
+    Range.Start = Result->Range.Start;
+    Range.End = currentLocation();
+    Error->pushErrorFrame(Range, Error->ET_ParserStringError)
+        << ErrorText;
+    Result->Kind = TokenInfo::TK_Error;
+  }
+
+  /// \brief Consume all leading whitespace from \c Code.
+  void consumeWhitespace() {
+    while (!Code.empty() && isWhitespace(Code[0])) {
+      if (Code[0] == '\n') {
+        ++Line;
+        StartOfLine = Code.drop_front();
+      }
+      Code = Code.drop_front();
+    }
+  }
+
+  SourceLocation currentLocation() {
+    SourceLocation Location;
+    Location.Line = Line;
+    Location.Column = Code.data() - StartOfLine.data() + 1;
+    return Location;
+  }
+
+  StringRef Code;
+  StringRef StartOfLine;
+  unsigned Line;
+  Diagnostics *Error;
+  TokenInfo NextToken;
+};
+
+Parser::Sema::~Sema() {}
+
+/// \brief Parse and validate a matcher expression.
+/// \return \c true on success, in which case \c Value has the matcher parsed.
+///   If the input is malformed, or some argument has an error, it
+///   returns \c false.
+bool Parser::parseMatcherExpressionImpl(VariantValue *Value) {
+  const TokenInfo NameToken = Tokenizer->consumeNextToken();
+  assert(NameToken.Kind == TokenInfo::TK_Ident);
+  const TokenInfo OpenToken = Tokenizer->consumeNextToken();
+  if (OpenToken.Kind != TokenInfo::TK_OpenParen) {
+    Error->pushErrorFrame(OpenToken.Range, Error->ET_ParserNoOpenParen)
+        << OpenToken.Text;
+    return false;
+  }
+
+  std::vector<ParserValue> Args;
+  TokenInfo EndToken;
+  while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
+    if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) {
+      // End of args.
+      EndToken = Tokenizer->consumeNextToken();
+      break;
+    }
+    if (Args.size() > 0) {
+      // We must find a , token to continue.
+      const TokenInfo CommaToken = Tokenizer->consumeNextToken();
+      if (CommaToken.Kind != TokenInfo::TK_Comma) {
+        Error->pushErrorFrame(CommaToken.Range, Error->ET_ParserNoComma)
+            << CommaToken.Text;
+        return false;
+      }
+    }
+
+    ParserValue ArgValue;
+    ArgValue.Text = Tokenizer->peekNextToken().Text;
+    ArgValue.Range = Tokenizer->peekNextToken().Range;
+    if (!parseExpressionImpl(&ArgValue.Value)) {
+      Error->pushErrorFrame(NameToken.Range,
+                            Error->ET_ParserMatcherArgFailure)
+          << (Args.size() + 1) << NameToken.Text;
+      return false;
+    }
+
+    Args.push_back(ArgValue);
+  }
+
+  if (EndToken.Kind == TokenInfo::TK_Eof) {
+    Error->pushErrorFrame(OpenToken.Range, Error->ET_ParserNoCloseParen);
+    return false;
+  }
+
+  // Merge the start and end infos.
+  SourceRange MatcherRange = NameToken.Range;
+  MatcherRange.End = EndToken.Range.End;
+  DynTypedMatcher *Result =
+      S->actOnMatcherExpression(NameToken.Text, MatcherRange, Args, Error);
+  if (Result == NULL) {
+    Error->pushErrorFrame(NameToken.Range, Error->ET_ParserMatcherFailure)
+        << NameToken.Text;
+    return false;
+  }
+
+  Value->takeMatcher(Result);
+  return true;
+}
+
+/// \brief Parse an <Expresssion>
+bool Parser::parseExpressionImpl(VariantValue *Value) {
+  switch (Tokenizer->nextTokenKind()) {
+  case TokenInfo::TK_Literal:
+    *Value = Tokenizer->consumeNextToken().Value;
+    return true;
+
+  case TokenInfo::TK_Ident:
+    return parseMatcherExpressionImpl(Value);
+
+  case TokenInfo::TK_Eof:
+    Error->pushErrorFrame(Tokenizer->consumeNextToken().Range,
+                          Error->ET_ParserNoCode);
+    return false;
+
+  case TokenInfo::TK_Error:
+    // This error was already reported by the tokenizer.
+    return false;
+
+  case TokenInfo::TK_OpenParen:
+  case TokenInfo::TK_CloseParen:
+  case TokenInfo::TK_Comma:
+  case TokenInfo::TK_InvalidChar:
+    const TokenInfo Token = Tokenizer->consumeNextToken();
+    Error->pushErrorFrame(Token.Range, Error->ET_ParserInvalidToken)
+        << Token.Text;
+    return false;
+  }
+
+  llvm_unreachable("Unknown token kind.");
+}
+
+Parser::Parser(CodeTokenizer *Tokenizer, Sema *S,
+               Diagnostics *Error)
+    : Tokenizer(Tokenizer), S(S), Error(Error) {}
+
+class RegistrySema : public Parser::Sema {
+public:
+  virtual ~RegistrySema() {}
+  DynTypedMatcher *actOnMatcherExpression(StringRef MatcherName,
+                                          const SourceRange &NameRange,
+                                          ArrayRef<ParserValue> Args,
+                                          Diagnostics *Error) {
+    return Registry::constructMatcher(MatcherName, NameRange, Args, Error);
+  }
+};
+
+bool Parser::parseExpression(StringRef Code, VariantValue *Value,
+                             Diagnostics *Error) {
+  RegistrySema S;
+  return parseExpression(Code, &S, Value, Error);
+}
+
+bool Parser::parseExpression(StringRef Code, Sema *S,
+                             VariantValue *Value, Diagnostics *Error) {
+  CodeTokenizer Tokenizer(Code, Error);
+  return Parser(&Tokenizer, S, Error).parseExpressionImpl(Value);
+}
+
+DynTypedMatcher *Parser::parseMatcherExpression(StringRef Code,
+                                                Diagnostics *Error) {
+  RegistrySema S;
+  return parseMatcherExpression(Code, &S, Error);
+}
+
+DynTypedMatcher *Parser::parseMatcherExpression(StringRef Code,
+                                                Parser::Sema *S,
+                                                Diagnostics *Error) {
+  VariantValue Value;
+  if (!parseExpression(Code, S, &Value, Error))
+    return NULL;
+  if (!Value.isMatcher()) {
+    Error->pushErrorFrame(SourceRange(), Error->ET_ParserNotAMatcher);
+    return NULL;
+  }
+  return Value.getMatcher().clone();
+}
+
+}  // namespace dynamic
+}  // namespace ast_matchers
+}  // namespace clang
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
new file mode 100644
index 0000000..53e90f1
--- /dev/null
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -0,0 +1,153 @@
+//===--- Registry.cpp - Matcher registry ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Registry map populated at static initialization time.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/ASTMatchers/Dynamic/Registry.h"
+
+#include <utility>
+
+#include "Marshallers.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ManagedStatic.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+namespace {
+
+using internal::MatcherCreateCallback;
+
+typedef llvm::StringMap<const MatcherCreateCallback *> ConstructorMap;
+class RegistryMaps {
+public:
+  RegistryMaps();
+  ~RegistryMaps();
+
+  const ConstructorMap &constructors() const { return Constructors; }
+
+private:
+  void registerMatcher(StringRef MatcherName, MatcherCreateCallback *Callback);
+  ConstructorMap Constructors;
+};
+
+void RegistryMaps::registerMatcher(StringRef MatcherName,
+                                   MatcherCreateCallback *Callback) {
+  Constructors[MatcherName] = Callback;
+}
+
+#define REGISTER_MATCHER(name)                                                 \
+  registerMatcher(#name, internal::makeMatcherAutoMarshall(                    \
+                             ::clang::ast_matchers::name, #name));
+
+/// \brief Generate a registry map with all the known matchers.
+RegistryMaps::RegistryMaps() {
+  // TODO: This list is not complete. It only has non-overloaded matchers,
+  // which are the simplest to add to the system. Overloaded matchers require
+  // more supporting code that was omitted from the first revision for
+  // simplicitly of code review.
+
+  REGISTER_MATCHER(binaryOperator);
+  REGISTER_MATCHER(bindTemporaryExpr);
+  REGISTER_MATCHER(boolLiteral);
+  REGISTER_MATCHER(callExpr);
+  REGISTER_MATCHER(characterLiteral);
+  REGISTER_MATCHER(compoundStmt);
+  REGISTER_MATCHER(conditionalOperator);
+  REGISTER_MATCHER(constCastExpr);
+  REGISTER_MATCHER(constructExpr);
+  REGISTER_MATCHER(constructorDecl);
+  REGISTER_MATCHER(declRefExpr);
+  REGISTER_MATCHER(declStmt);
+  REGISTER_MATCHER(defaultArgExpr);
+  REGISTER_MATCHER(doStmt);
+  REGISTER_MATCHER(dynamicCastExpr);
+  REGISTER_MATCHER(explicitCastExpr);
+  REGISTER_MATCHER(expr);
+  REGISTER_MATCHER(fieldDecl);
+  REGISTER_MATCHER(forStmt);
+  REGISTER_MATCHER(functionDecl);
+  REGISTER_MATCHER(hasAnyParameter);
+  REGISTER_MATCHER(hasAnySubstatement);
+  REGISTER_MATCHER(hasConditionVariableStatement);
+  REGISTER_MATCHER(hasDestinationType);
+  REGISTER_MATCHER(hasEitherOperand);
+  REGISTER_MATCHER(hasFalseExpression);
+  REGISTER_MATCHER(hasImplicitDestinationType);
+  REGISTER_MATCHER(hasInitializer);
+  REGISTER_MATCHER(hasLHS);
+  REGISTER_MATCHER(hasName);
+  REGISTER_MATCHER(hasObjectExpression);
+  REGISTER_MATCHER(hasRHS);
+  REGISTER_MATCHER(hasSourceExpression);
+  REGISTER_MATCHER(hasTrueExpression);
+  REGISTER_MATCHER(hasUnaryOperand);
+  REGISTER_MATCHER(ifStmt);
+  REGISTER_MATCHER(implicitCastExpr);
+  REGISTER_MATCHER(integerLiteral);
+  REGISTER_MATCHER(isArrow);
+  REGISTER_MATCHER(isConstQualified);
+  REGISTER_MATCHER(isImplicit);
+  REGISTER_MATCHER(member);
+  REGISTER_MATCHER(memberExpr);
+  REGISTER_MATCHER(methodDecl);
+  REGISTER_MATCHER(namedDecl);
+  REGISTER_MATCHER(newExpr);
+  REGISTER_MATCHER(ofClass);
+  REGISTER_MATCHER(on);
+  REGISTER_MATCHER(onImplicitObjectArgument);
+  REGISTER_MATCHER(operatorCallExpr);
+  REGISTER_MATCHER(recordDecl);
+  REGISTER_MATCHER(reinterpretCastExpr);
+  REGISTER_MATCHER(staticCastExpr);
+  REGISTER_MATCHER(stmt);
+  REGISTER_MATCHER(stringLiteral);
+  REGISTER_MATCHER(switchCase);
+  REGISTER_MATCHER(to);
+  REGISTER_MATCHER(unaryOperator);
+  REGISTER_MATCHER(varDecl);
+  REGISTER_MATCHER(whileStmt);
+}
+
+RegistryMaps::~RegistryMaps() {
+  for (ConstructorMap::iterator it = Constructors.begin(),
+                                end = Constructors.end();
+       it != end; ++it) {
+    delete it->second;
+  }
+}
+
+static llvm::ManagedStatic<RegistryMaps> RegistryData;
+
+} // anonymous namespace
+
+// static
+DynTypedMatcher *Registry::constructMatcher(StringRef MatcherName,
+                                            const SourceRange &NameRange,
+                                            ArrayRef<ParserValue> Args,
+                                            Diagnostics *Error) {
+  ConstructorMap::const_iterator it =
+      RegistryData->constructors().find(MatcherName);
+  if (it == RegistryData->constructors().end()) {
+    Error->pushErrorFrame(NameRange, Error->ET_RegistryNotFound)
+        << MatcherName;
+    return NULL;
+  }
+
+  return it->second->run(NameRange, Args, Error);
+}
+
+}  // namespace dynamic
+}  // namespace ast_matchers
+}  // namespace clang
diff --git a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
new file mode 100644
index 0000000..e310fbf
--- /dev/null
+++ b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -0,0 +1,105 @@
+//===--- VariantValue.cpp - Polymorphic value type -*- C++ -*-===/
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Polymorphic value type.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/ASTMatchers/Dynamic/VariantValue.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
+  *this = Other;
+}
+
+VariantValue::VariantValue(const DynTypedMatcher &Matcher) : Type(VT_Nothing) {
+  setMatcher(Matcher);
+}
+
+VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) {
+  setString(String);
+}
+
+VariantValue::~VariantValue() { reset(); }
+
+VariantValue &VariantValue::operator=(const VariantValue &Other) {
+  if (this == &Other) return *this;
+  reset();
+  switch (Other.Type) {
+  case VT_String:
+    setString(Other.getString());
+    break;
+  case VT_Matcher:
+    setMatcher(Other.getMatcher());
+    break;
+  case VT_Nothing:
+    Type = VT_Nothing;
+    break;
+  }
+  return *this;
+}
+
+void VariantValue::reset() {
+  switch (Type) {
+  case VT_String:
+    delete Value.String;
+    break;
+  case VT_Matcher:
+    delete Value.Matcher;
+    break;
+  // Cases that do nothing.
+  case VT_Nothing:
+    break;
+  }
+  Type = VT_Nothing;
+}
+
+bool VariantValue::isString() const {
+  return Type == VT_String;
+}
+
+const std::string &VariantValue::getString() const {
+  assert(isString());
+  return *Value.String;
+}
+
+void VariantValue::setString(const std::string &NewValue) {
+  reset();
+  Type = VT_String;
+  Value.String = new std::string(NewValue);
+}
+
+bool VariantValue::isMatcher() const {
+  return Type == VT_Matcher;
+}
+
+const DynTypedMatcher &VariantValue::getMatcher() const {
+  assert(isMatcher());
+  return *Value.Matcher;
+}
+
+void VariantValue::setMatcher(const DynTypedMatcher &NewValue) {
+  reset();
+  Type = VT_Matcher;
+  Value.Matcher = NewValue.clone();
+}
+
+void VariantValue::takeMatcher(DynTypedMatcher *NewValue) {
+  reset();
+  Type = VT_Matcher;
+  Value.Matcher = NewValue;
+}
+
+} // end namespace dynamic
+} // end namespace ast_matchers
+} // end namespace clang