[cfe-commits] r160013 - in /cfe/trunk: include/clang/ASTMatchers/ASTMatchers.h include/clang/ASTMatchers/ASTMatchersInternal.h lib/ASTMatchers/ASTMatchFinder.cpp lib/ASTMatchers/ASTMatchersInternal.cpp unittests/ASTMatchers/ASTMatchersTest.cpp

Daniel Jasper djasper at google.com
Tue Jul 10 13:20:19 PDT 2012


Author: djasper
Date: Tue Jul 10 15:20:19 2012
New Revision: 160013

URL: http://llvm.org/viewvc/llvm-project?rev=160013&view=rev
Log:
    Add more matchers and do cleanups.

    Reviewers: klimek

    Differential Revision: http://ec2-50-18-127-156.us-west-1.compute.amazonaws.com/D2

Modified:
    cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
    cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
    cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp
    cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=160013&r1=160012&r2=160013&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Tue Jul 10 15:20:19 2012
@@ -45,9 +45,11 @@
 #ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
 #define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
 
+#include "clang/AST/DeclTemplate.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
 #include "clang/ASTMatchers/ASTMatchersMacros.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/Support/Regex.h"
 
 namespace clang {
 namespace ast_matchers {
@@ -78,8 +80,8 @@
 
 private:
   /// \brief 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)
+  BoundNodes(const std::map<std::string, const Decl*> &DeclBindings,
+             const std::map<std::string, const Stmt*> &StmtBindings)
       : DeclBindings(DeclBindings), StmtBindings(StmtBindings) {}
 
   template <typename T, typename MapT>
@@ -91,8 +93,8 @@
     return llvm::dyn_cast<T>(It->second);
   }
 
-  std::map<std::string, const clang::Decl*> DeclBindings;
-  std::map<std::string, const clang::Stmt*> StmtBindings;
+  std::map<std::string, const Decl*> DeclBindings;
+  std::map<std::string, const Stmt*> StmtBindings;
 
   friend class internal::BoundNodesTree;
 };
@@ -109,9 +111,9 @@
 /// \brief Types of matchers for the top-level classes in the AST class
 /// hierarchy.
 /// @{
-typedef internal::Matcher<clang::Decl> DeclarationMatcher;
-typedef internal::Matcher<clang::QualType> TypeMatcher;
-typedef internal::Matcher<clang::Stmt> StatementMatcher;
+typedef internal::Matcher<Decl> DeclarationMatcher;
+typedef internal::Matcher<QualType> TypeMatcher;
+typedef internal::Matcher<Stmt> StatementMatcher;
 /// @}
 
 /// \brief Matches any node.
@@ -138,8 +140,8 @@
 ///     } U;
 ///   };
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Decl,
-  clang::NamedDecl> nameableDeclaration;
+  Decl,
+  NamedDecl> nameableDeclaration;
 
 /// \brief Matches C++ class declarations.
 ///
@@ -147,8 +149,91 @@
 ///   class X;
 ///   template<class T> class Z {};
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Decl,
-  clang::CXXRecordDecl> record;
+  Decl,
+  CXXRecordDecl> record;
+
+/// \brief Matches C++ class template specializations.
+///
+/// Given
+///   template<typename T> class A {};
+///   template<> class A<double> {};
+///   A<int> a;
+/// classTemplateSpecialization()
+///   matches the specializations \c A<int> and \c A<double>
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  ClassTemplateSpecializationDecl> classTemplateSpecialization;
+
+/// \brief Matches classTemplateSpecializations that have at least one
+/// TemplateArgument matching the given Matcher.
+///
+/// Given
+///   template<typename T> class A {};
+///   template<> class A<double> {};
+///   A<int> a;
+/// classTemplateSpecialization(hasAnyTemplateArgument(
+///     refersToType(asString("int"))))
+///   matches the specialization \c A<int>
+AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument,
+              internal::Matcher<TemplateArgument>, Matcher) {
+  const TemplateArgumentList &List = Node.getTemplateArgs();
+  for (unsigned i = 0; i < List.size(); ++i) {
+    if (Matcher.matches(List.get(i), Finder, Builder))
+      return true;
+  }
+  return false;
+}
+
+/// \brief Matches classTemplateSpecializations where the n'th TemplateArgument
+/// matches the given Matcher.
+///
+/// Given
+///   template<typename T, typename U> class A {};
+///   A<bool, int> b;
+///   A<int, bool> c;
+/// classTemplateSpecialization(hasTemplateArgument(
+///     1, refersToType(asString("int"))))
+///   matches the specialization \c A<bool, int>
+AST_MATCHER_P2(ClassTemplateSpecializationDecl, hasTemplateArgument,
+               unsigned, N, internal::Matcher<TemplateArgument>, Matcher) {
+  const TemplateArgumentList &List = Node.getTemplateArgs();
+  if (List.size() <= N)
+    return false;
+  return Matcher.matches(List.get(N), Finder, Builder);
+}
+
+/// \brief Matches a TemplateArgument that refers to a certain type.
+///
+/// Given
+///   struct X {};
+///   template<typename T> struct A {};
+///   A<X> a;
+/// classTemplateSpecialization(hasAnyTemplateArgument(
+///     refersToType(class(hasName("X")))))
+///   matches the specialization \c A<X>
+AST_MATCHER_P(TemplateArgument, refersToType,
+              internal::Matcher<QualType>, Matcher) {
+  if (Node.getKind() != TemplateArgument::Type)
+    return false;
+  return Matcher.matches(Node.getAsType(), Finder, Builder);
+}
+
+/// \brief Matches a TemplateArgument that refers to a certain declaration.
+///
+/// Given
+///   template<typename T> struct A {};
+///   struct B { B* next; };
+///   A<&B::next> a;
+/// classTemplateSpecialization(hasAnyTemplateArgument(
+///     refersToDeclaration(field(hasName("next"))))
+///   matches the specialization \c A<&B::next> with \c field(...) matching
+///     \c B::next
+AST_MATCHER_P(TemplateArgument, refersToDeclaration,
+              internal::Matcher<Decl>, Matcher) {
+  if (const Decl *Declaration = Node.getAsDecl())
+    return Matcher.matches(*Declaration, Finder, Builder);
+  return false;
+}
 
 /// \brief Matches C++ constructor declarations.
 ///
@@ -160,16 +245,41 @@
 ///     int DoSomething();
 ///   };
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Decl,
-  clang::CXXConstructorDecl> constructor;
+  Decl,
+  CXXConstructorDecl> constructor;
+
+/// \brief Matches explicit C++ destructor declarations.
+///
+/// Example matches Foo::~Foo()
+///   class Foo {
+///    public:
+///     virtual ~Foo();
+///   };
+const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl> destructor;
+
+/// \brief Matches enum declarations.
+///
+/// Example matches X
+///   enum X {
+///     A, B, C
+///   };
+const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
+
+/// \brief Matches enum constants.
+///
+/// Example matches A, B, C
+///   enum X {
+///     A, B, C
+///   };
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  EnumConstantDecl> enumConstant;
 
 /// \brief Matches method declarations.
 ///
 /// Example matches y
 ///   class X { void y() };
-const internal::VariadicDynCastAllOfMatcher<
-  clang::Decl,
-  clang::CXXMethodDecl> method;
+const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> method;
 
 /// \brief Matches variable declarations.
 ///
@@ -178,9 +288,7 @@
 ///
 /// Example matches a
 ///   int a;
-const internal::VariadicDynCastAllOfMatcher<
-  clang::Decl,
-  clang::VarDecl> variable;
+const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> variable;
 
 /// \brief Matches field declarations.
 ///
@@ -188,17 +296,13 @@
 ///   class X { int m; };
 /// field()
 ///   matches 'm'.
-const internal::VariadicDynCastAllOfMatcher<
-  clang::Decl,
-  clang::FieldDecl> field;
+const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> field;
 
 /// \brief Matches function declarations.
 ///
 /// Example matches f
 ///   void f();
-const internal::VariadicDynCastAllOfMatcher<
-  clang::Decl,
-  clang::FunctionDecl> function;
+const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> function;
 
 
 /// \brief Matches statements.
@@ -207,7 +311,7 @@
 ///   { ++a; }
 /// statement()
 ///   matches both the compound statement '{ ++a; }' and '++a'.
-const internal::VariadicDynCastAllOfMatcher<clang::Stmt, clang::Stmt> statement;
+const internal::VariadicDynCastAllOfMatcher<Stmt, Stmt> statement;
 
 /// \brief Matches declaration statements.
 ///
@@ -216,8 +320,8 @@
 /// declarationStatement()
 ///   matches 'int a'.
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::DeclStmt> declarationStatement;
+  Stmt,
+  DeclStmt> declarationStatement;
 
 /// \brief Matches member expressions.
 ///
@@ -229,15 +333,34 @@
 /// memberExpression()
 ///   matches this->x, x, y.x, a, this->b
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::MemberExpr> memberExpression;
+  Stmt,
+  MemberExpr> memberExpression;
 
 /// \brief Matches call expressions.
 ///
 /// Example matches x.y()
 ///   X x;
 ///   x.y();
-const internal::VariadicDynCastAllOfMatcher<clang::Stmt, clang::CallExpr> call;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> call;
+
+/// \brief Matches init list expressions.
+///
+/// Given
+///   int a[] = { 1, 2 };
+///   struct B { int x, y; };
+///   B b = { 5, 6 };
+/// initList()
+///   matches "{ 1, 2 }" and "{ 5, 6 }"
+const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
+
+/// \brief Matches using declarations.
+///
+/// Given
+///   namespace X { int x; }
+///   using X::x;
+/// usingDecl()
+///   matches \code using X::x \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
 
 /// \brief Matches constructor call expressions (including implicit ones).
 ///
@@ -248,18 +371,18 @@
 ///   int n;
 ///   f(string(ptr, n), ptr);
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::CXXConstructExpr> constructorCall;
+  Stmt,
+  CXXConstructExpr> constructorCall;
 
 /// \brief Matches nodes where temporaries are created.
 ///
 /// Example matches FunctionTakesString(GetStringByValue())
-///     (matcher = bindTemporaryExpr())
+///     (matcher = bindTemporaryExpression())
 ///   FunctionTakesString(GetStringByValue());
 ///   FunctionTakesStringByPointer(GetStringPointer());
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::CXXBindTemporaryExpr> bindTemporaryExpression;
+  Stmt,
+  CXXBindTemporaryExpr> bindTemporaryExpression;
 
 /// \brief Matches new expressions.
 ///
@@ -268,8 +391,28 @@
 /// newExpression()
 ///   matches 'new X'.
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::CXXNewExpr> newExpression;
+  Stmt,
+  CXXNewExpr> newExpression;
+
+/// \brief Matches delete expressions.
+///
+/// Given
+///   delete X;
+/// deleteExpression()
+///   matches 'delete X'.
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXDeleteExpr> deleteExpression;
+
+/// \brief Matches array subscript expressions.
+///
+/// Given
+///   int i = a[1];
+/// arraySubscriptExpr()
+///   matches "a[1]"
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  ArraySubscriptExpr> arraySubscriptExpr;
 
 /// \brief Matches the value of a default argument at the call site.
 ///
@@ -279,8 +422,8 @@
 ///   void f(int x, int y = 0);
 ///   f(42);
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::CXXDefaultArgExpr> defaultArgument;
+  Stmt,
+  CXXDefaultArgExpr> defaultArgument;
 
 /// \brief Matches overloaded operator calls.
 ///
@@ -295,16 +438,16 @@
 ///   ostream &o; int b = 1, c = 1;
 ///   o << b << c;
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::CXXOperatorCallExpr> overloadedOperatorCall;
+  Stmt,
+  CXXOperatorCallExpr> overloadedOperatorCall;
 
 /// \brief Matches expressions.
 ///
 /// Example matches x()
 ///   void f() { x(); }
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::Expr> expression;
+  Stmt,
+  Expr> expression;
 
 /// \brief Matches expressions that refer to declarations.
 ///
@@ -312,21 +455,21 @@
 ///   bool x;
 ///   if (x) {}
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::DeclRefExpr> declarationReference;
+  Stmt,
+  DeclRefExpr> declarationReference;
 
 /// \brief Matches if statements.
 ///
 /// Example matches 'if (x) {}'
 ///   if (x) {}
-const internal::VariadicDynCastAllOfMatcher<clang::Stmt, clang::IfStmt> ifStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
 
 /// \brief Matches for statements.
 ///
 /// Example matches 'for (;;) {}'
 ///   for (;;) {}
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt, clang::ForStmt> forStmt;
+  Stmt, ForStmt> forStmt;
 
 /// \brief Matches while statements.
 ///
@@ -335,8 +478,8 @@
 /// whileStmt()
 ///   matches 'while (true) {}'.
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::WhileStmt> whileStmt;
+  Stmt,
+  WhileStmt> whileStmt;
 
 /// \brief Matches do statements.
 ///
@@ -344,7 +487,7 @@
 ///   do {} while (true);
 /// doStmt()
 ///   matches 'do {} while(true)'
-const internal::VariadicDynCastAllOfMatcher<clang::Stmt, clang::DoStmt> doStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
 
 /// \brief Matches case and default statements inside switch statements.
 ///
@@ -353,32 +496,32 @@
 /// switchCase()
 ///   matches 'case 42: break;' and 'default: break;'.
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::SwitchCase> switchCase;
+  Stmt,
+  SwitchCase> switchCase;
 
 /// \brief Matches compound statements.
 ///
 /// Example matches '{}' and '{{}}'in 'for (;;) {{}}'
 ///   for (;;) {{}}
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::CompoundStmt> compoundStatement;
+  Stmt,
+  CompoundStmt> compoundStatement;
 
 /// \brief Matches bool literals.
 ///
 /// Example matches true
 ///   true
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::CXXBoolLiteralExpr> boolLiteral;
+  Expr,
+  CXXBoolLiteralExpr> boolLiteral;
 
 /// \brief Matches string literals (also matches wide string literals).
 ///
 /// Example matches "abcd", L"abcd"
 ///   char *s = "abcd"; wchar_t *ws = L"abcd"
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::StringLiteral> stringLiteral;
+  Expr,
+  StringLiteral> stringLiteral;
 
 /// \brief Matches character literals (also matches wchar_t).
 ///
@@ -388,8 +531,8 @@
 /// Example matches 'a', L'a'
 ///   char ch = 'a'; wchar_t chw = L'a';
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::CharacterLiteral> characterLiteral;
+  Expr,
+  CharacterLiteral> characterLiteral;
 
 /// \brief Matches integer literals of all sizes / encodings.
 ///
@@ -397,32 +540,32 @@
 ///
 /// Example matches 1, 1L, 0x1, 1U
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::IntegerLiteral> integerLiteral;
+  Expr,
+  IntegerLiteral> integerLiteral;
 
 /// \brief Matches binary operator expressions.
 ///
 /// Example matches a || b
 ///   !(a || b)
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::BinaryOperator> binaryOperator;
+  Stmt,
+  BinaryOperator> binaryOperator;
 
 /// \brief Matches unary operator expressions.
 ///
 /// Example matches !a
 ///   !a || b
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::UnaryOperator> unaryOperator;
+  Stmt,
+  UnaryOperator> unaryOperator;
 
 /// \brief Matches conditional operator expressions.
 ///
 /// Example matches a ? b : c
 ///   (a ? b : c) + 42
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Stmt,
-  clang::ConditionalOperator> conditionalOperator;
+  Stmt,
+  ConditionalOperator> conditionalOperator;
 
 /// \brief Matches a reinterpret_cast expression.
 ///
@@ -433,8 +576,8 @@
 /// Example matches reinterpret_cast<char*>(&p) in
 ///   void* p = reinterpret_cast<char*>(&p);
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::CXXReinterpretCastExpr> reinterpretCast;
+  Expr,
+  CXXReinterpretCastExpr> reinterpretCast;
 
 /// \brief Matches a C++ static_cast expression.
 ///
@@ -448,8 +591,8 @@
 /// in
 ///   long eight(static_cast<long>(8));
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::CXXStaticCastExpr> staticCast;
+  Expr,
+  CXXStaticCastExpr> staticCast;
 
 /// \brief Matches a dynamic_cast expression.
 ///
@@ -462,8 +605,8 @@
 ///   B b;
 ///   D* p = dynamic_cast<D*>(&b);
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::CXXDynamicCastExpr> dynamicCast;
+  Expr,
+  CXXDynamicCastExpr> dynamicCast;
 
 /// \brief Matches a const_cast expression.
 ///
@@ -472,8 +615,8 @@
 ///   const int& r(n);
 ///   int* p = const_cast<int*>(&r);
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::CXXConstCastExpr> constCast;
+  Expr,
+  CXXConstCastExpr> constCast;
 
 /// \brief Matches explicit cast expressions.
 ///
@@ -493,16 +636,16 @@
 /// but does not match the implicit conversion in
 ///   long ell = 42;
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::ExplicitCastExpr> explicitCast;
+  Expr,
+  ExplicitCastExpr> explicitCast;
 
 /// \brief Matches the implicit cast nodes of Clang's AST.
 ///
 /// This matches many different places, including function call return value
 /// eliding, as well as any type conversions.
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::ImplicitCastExpr> implicitCast;
+  Expr,
+  ImplicitCastExpr> implicitCast;
 
 /// \brief Matches functional cast expressions
 ///
@@ -511,8 +654,8 @@
 ///   Foo g = (Foo) bar;
 ///   Foo h = Foo(bar);
 const internal::VariadicDynCastAllOfMatcher<
-  clang::Expr,
-  clang::CXXFunctionalCastExpr> functionalCast;
+  Expr,
+  CXXFunctionalCastExpr> functionalCast;
 
 /// \brief Various overloads for the anyOf matcher.
 /// @{
@@ -563,6 +706,56 @@
 }
 /// @}
 
+/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
+///
+/// Given
+///   Foo x = bar;
+///   int y = sizeof(x) + alignof(x);
+/// unaryExprOrTypeTraitExpr()
+///   matches \c sizeof(x) and \c alignof(x)
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  UnaryExprOrTypeTraitExpr> unaryExprOrTypeTraitExpr;
+
+/// \brief Matches unary expressions that have a specific type of argument.
+///
+/// Given
+///   int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c);
+/// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
+///   matches \c sizeof(a) and \c alignof(c)
+AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType,
+              internal::Matcher<QualType>, Matcher) {
+  const QualType ArgumentType = Node.getTypeOfArgument();
+  return Matcher.matches(ArgumentType, Finder, Builder);
+}
+
+/// \brief Matches unary expressions of a certain kind.
+///
+/// Given
+///   int x;
+///   int s = sizeof(x) + alignof(x)
+/// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
+///   matches \c sizeof(x)
+AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
+  return Node.getKind() == Kind;
+}
+
+/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
+/// alignof.
+inline internal::Matcher<Stmt> alignOfExpr(
+    const internal::Matcher<UnaryExprOrTypeTraitExpr> &Matcher) {
+  return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
+      ofKind(UETT_AlignOf), Matcher)));
+}
+
+/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
+/// sizeof.
+inline internal::Matcher<Stmt> sizeOfExpr(
+    const internal::Matcher<UnaryExprOrTypeTraitExpr> &Matcher) {
+  return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
+      ofKind(UETT_SizeOf), Matcher)));
+}
+
 /// \brief Matches NamedDecl nodes that have the specified name.
 ///
 /// Supports specifying enclosing namespaces or classes by prefixing the name
@@ -574,7 +767,7 @@
 ///
 /// 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) {
+AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
   assert(!Name.empty());
   const std::string FullNameString = "::" + Node.getQualifiedNameAsString();
   const llvm::StringRef FullName = FullNameString;
@@ -586,6 +779,25 @@
   }
 }
 
+/// \brief Matches NamedDecl nodes whose full names partially match the
+/// given RegExp.
+///
+/// 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 (regexp == "::X")
+///   class X;
+///
+/// Example matches X (regexp is one of "::X", "^foo::.*X", among others)
+/// namespace foo { namespace bar { class X; } }
+AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
+  assert(!RegExp.empty());
+  std::string FullNameString = "::" + Node.getQualifiedNameAsString();
+  llvm::Regex RE(RegExp);
+  return RE.match(FullNameString);
+}
+
 /// \brief Matches overloaded operator names.
 ///
 /// Matches overloaded operator names specified in strings without the
@@ -596,9 +808,9 @@
 ///   a << b;
 ///   c && d;  // assuming both operator<<
 ///            // and operator&& are overloaded somewhere.
-AST_MATCHER_P(clang::CXXOperatorCallExpr,
+AST_MATCHER_P(CXXOperatorCallExpr,
               hasOverloadedOperatorName, std::string, Name) {
-  return clang::getOperatorSpelling(Node.getOperator()) == Name;
+  return getOperatorSpelling(Node.getOperator()) == Name;
 }
 
 /// \brief Matches C++ classes that are directly or indirectly derived from
@@ -621,7 +833,7 @@
 ///   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) {
+AST_MATCHER_P(CXXRecordDecl, isDerivedFrom, std::string, Base) {
   assert(!Base.empty());
   return Finder->classIsDerivedFrom(&Node, Base);
 }
@@ -722,11 +934,11 @@
 /// \brief Matches a type if the declaration of the type matches the given
 /// matcher.
 inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
-                                     internal::Matcher<clang::Decl> >
-    hasDeclaration(const internal::Matcher<clang::Decl> &InnerMatcher) {
+                                     internal::Matcher<Decl> >
+    hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
   return internal::PolymorphicMatcherWithParam1<
     internal::HasDeclarationMatcher,
-    internal::Matcher<clang::Decl> >(InnerMatcher);
+    internal::Matcher<Decl> >(InnerMatcher);
 }
 
 /// \brief Matches on the implicit object argument of a member call expression.
@@ -736,9 +948,9 @@
 ///   void z() { Y y; y.x(); }",
 ///
 /// FIXME: Overload to allow directly matching types?
-AST_MATCHER_P(clang::CXXMemberCallExpr, on, internal::Matcher<clang::Expr>,
+AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
               InnerMatcher) {
-  const clang::Expr *ExprNode = const_cast<clang::CXXMemberCallExpr&>(Node)
+  const Expr *ExprNode = const_cast<CXXMemberCallExpr&>(Node)
       .getImplicitObjectArgument()
       ->IgnoreParenImpCasts();
   return (ExprNode != NULL &&
@@ -755,13 +967,13 @@
 /// with callee(...)
 ///   matching this->x, x, y.x, f respectively
 ///
-/// Note: Callee cannot take the more general internal::Matcher<clang::Expr>
+/// Note: Callee cannot take the more general internal::Matcher<Expr>
 /// because this introduces ambiguous overloads with calls to Callee taking a
-/// internal::Matcher<clang::Decl>, as the matcher hierarchy is purely
+/// internal::Matcher<Decl>, as the matcher hierarchy is purely
 /// implemented in terms of implicit casts.
-AST_MATCHER_P(clang::CallExpr, callee, internal::Matcher<clang::Stmt>,
+AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
               InnerMatcher) {
-  const clang::Expr *ExprNode = Node.getCallee();
+  const Expr *ExprNode = Node.getCallee();
   return (ExprNode != NULL &&
           InnerMatcher.matches(*ExprNode, Finder, Builder));
 }
@@ -772,9 +984,9 @@
 /// Example matches y.x() (matcher = call(callee(method(hasName("x")))))
 ///   class Y { public: void x(); };
 ///   void z() { Y y; y.x();
-inline internal::Matcher<clang::CallExpr> callee(
-    const internal::Matcher<clang::Decl> &InnerMatcher) {
-  return internal::Matcher<clang::CallExpr>(hasDeclaration(InnerMatcher));
+inline internal::Matcher<CallExpr> callee(
+    const internal::Matcher<Decl> &InnerMatcher) {
+  return internal::Matcher<CallExpr>(hasDeclaration(InnerMatcher));
 }
 
 /// \brief Matches if the expression's or declaration's type matches a type
@@ -786,10 +998,10 @@
 ///                        hasDeclaration(record(hasName("X"))))))
 ///  class X {};
 ///  void y(X &x) { x; X z; }
-AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher<clang::QualType>,
+AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher<QualType>,
                           InnerMatcher) {
-  TOOLING_COMPILE_ASSERT((llvm::is_base_of<clang::Expr, NodeType>::value ||
-                          llvm::is_base_of<clang::ValueDecl, NodeType>::value),
+  TOOLING_COMPILE_ASSERT((llvm::is_base_of<Expr, NodeType>::value ||
+                          llvm::is_base_of<ValueDecl, NodeType>::value),
                          instantiated_with_wrong_types);
   return InnerMatcher.matches(Node.getType(), Finder, Builder);
 }
@@ -809,12 +1021,23 @@
 ///  void y(X &x) { x; X z; }
 inline internal::PolymorphicMatcherWithParam1<
   internal::matcher_hasTypeMatcher,
-  internal::Matcher<clang::QualType> >
-hasType(const internal::Matcher<clang::Decl> &InnerMatcher) {
-  return hasType(internal::Matcher<clang::QualType>(
+  internal::Matcher<QualType> >
+hasType(const internal::Matcher<Decl> &InnerMatcher) {
+  return hasType(internal::Matcher<QualType>(
     hasDeclaration(InnerMatcher)));
 }
 
+/// \brief Matches if the matched type is represented by the given string.
+///
+/// Given
+///   class Y { public: void x(); };
+///   void z() { Y* y; y->x(); }
+/// call(on(hasType(asString("class Y *"))))
+///   matches y->x()
+AST_MATCHER_P(QualType, asString, std::string, Name) {
+  return Name == Node.getAsString();
+}
+
 /// \brief Matches if the matched type is a pointer type and the pointee type
 /// matches the specified matcher.
 ///
@@ -823,16 +1046,16 @@
 ///   class Y { public: void x(); };
 ///   void z() { Y *y; y->x(); }
 AST_MATCHER_P(
-    clang::QualType, pointsTo, internal::Matcher<clang::QualType>,
+    QualType, pointsTo, internal::Matcher<QualType>,
     InnerMatcher) {
-  return (Node->isPointerType() &&
+  return (!Node.isNull() && Node->isPointerType() &&
           InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
 }
 
 /// \brief Overloaded to match the pointee type's declaration.
-inline internal::Matcher<clang::QualType> pointsTo(
-    const internal::Matcher<clang::Decl> &InnerMatcher) {
-  return pointsTo(internal::Matcher<clang::QualType>(
+inline internal::Matcher<QualType> pointsTo(
+    const internal::Matcher<Decl> &InnerMatcher) {
+  return pointsTo(internal::Matcher<QualType>(
     hasDeclaration(InnerMatcher)));
 }
 
@@ -846,38 +1069,38 @@
 ///       X &x = b;
 ///       const X &y = b;
 ///   };
-AST_MATCHER_P(clang::QualType, references, internal::Matcher<clang::QualType>,
+AST_MATCHER_P(QualType, references, internal::Matcher<QualType>,
               InnerMatcher) {
-  return (Node->isReferenceType() &&
+  return (!Node.isNull() && Node->isReferenceType() &&
           InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
 }
 
 /// \brief Overloaded to match the referenced type's declaration.
-inline internal::Matcher<clang::QualType> references(
-    const internal::Matcher<clang::Decl> &InnerMatcher) {
-  return references(internal::Matcher<clang::QualType>(
+inline internal::Matcher<QualType> references(
+    const internal::Matcher<Decl> &InnerMatcher) {
+  return references(internal::Matcher<QualType>(
     hasDeclaration(InnerMatcher)));
 }
 
-AST_MATCHER_P(clang::CXXMemberCallExpr, onImplicitObjectArgument,
-              internal::Matcher<clang::Expr>, InnerMatcher) {
-  const clang::Expr *ExprNode =
-      const_cast<clang::CXXMemberCallExpr&>(Node).getImplicitObjectArgument();
+AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
+              internal::Matcher<Expr>, InnerMatcher) {
+  const Expr *ExprNode =
+      const_cast<CXXMemberCallExpr&>(Node).getImplicitObjectArgument();
   return (ExprNode != NULL &&
           InnerMatcher.matches(*ExprNode, Finder, Builder));
 }
 
 /// \brief Matches if the expression's type either matches the specified
 /// matcher, or is a pointer to a type that matches the InnerMatcher.
-inline internal::Matcher<clang::CallExpr> thisPointerType(
-    const internal::Matcher<clang::QualType> &InnerMatcher) {
+inline internal::Matcher<CallExpr> thisPointerType(
+    const internal::Matcher<QualType> &InnerMatcher) {
   return onImplicitObjectArgument(
       anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))));
 }
 
 /// \brief Overloaded to match the type's declaration.
-inline internal::Matcher<clang::CallExpr> thisPointerType(
-    const internal::Matcher<clang::Decl> &InnerMatcher) {
+inline internal::Matcher<CallExpr> thisPointerType(
+    const internal::Matcher<Decl> &InnerMatcher) {
   return onImplicitObjectArgument(
       anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))));
 }
@@ -889,13 +1112,36 @@
 ///     (matcher = declarationReference(to(variable(hasName("x")))))
 ///   bool x;
 ///   if (x) {}
-AST_MATCHER_P(clang::DeclRefExpr, to, internal::Matcher<clang::Decl>,
+AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
               InnerMatcher) {
-  const clang::Decl *DeclNode = Node.getDecl();
+  const Decl *DeclNode = Node.getDecl();
   return (DeclNode != NULL &&
           InnerMatcher.matches(*DeclNode, Finder, Builder));
 }
 
+/// \brief Matches a \c DeclRefExpr that refers to a declaration through a
+/// specific using shadow declaration.
+///
+/// FIXME: This currently only works for functions. Fix.
+///
+/// Given
+///   namespace a { void f() {} }
+///   using a::f;
+///   void g() {
+///     f();     // Matches this ..
+///     a::f();  // .. but not this.
+///   }
+/// declarationReference(throughUsingDeclaration(anything()))
+///   matches \c f()
+AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
+              internal::Matcher<UsingShadowDecl>, Matcher) {
+  const NamedDecl *FoundDecl = Node.getFoundDecl();
+  if (const UsingShadowDecl *UsingDecl =
+      llvm::dyn_cast<UsingShadowDecl>(FoundDecl))
+    return Matcher.matches(*UsingDecl, Finder, Builder);
+  return false;
+}
+
 /// \brief Matches a variable declaration that has an initializer expression
 /// that matches the given matcher.
 ///
@@ -903,9 +1149,9 @@
 ///   bool y() { return true; }
 ///   bool x = y();
 AST_MATCHER_P(
-    clang::VarDecl, hasInitializer, internal::Matcher<clang::Expr>,
+    VarDecl, hasInitializer, internal::Matcher<Expr>,
     InnerMatcher) {
-  const clang::Expr *Initializer = Node.getAnyInitializer();
+  const Expr *Initializer = Node.getAnyInitializer();
   return (Initializer != NULL &&
           InnerMatcher.matches(*Initializer, Finder, Builder));
 }
@@ -917,8 +1163,8 @@
 ///   void f(int x, int y);
 ///   f(0, 0);
 AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) {
-  TOOLING_COMPILE_ASSERT((llvm::is_base_of<clang::CallExpr, NodeType>::value ||
-                          llvm::is_base_of<clang::CXXConstructExpr,
+  TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value ||
+                          llvm::is_base_of<CXXConstructExpr,
                                            NodeType>::value),
                          instantiated_with_wrong_types);
   return Node.getNumArgs() == N;
@@ -931,9 +1177,9 @@
 ///     (matcher = call(hasArgument(0, declarationReference())))
 ///   void x(int) { int y; x(y); }
 AST_POLYMORPHIC_MATCHER_P2(
-    hasArgument, unsigned, N, internal::Matcher<clang::Expr>, InnerMatcher) {
-  TOOLING_COMPILE_ASSERT((llvm::is_base_of<clang::CallExpr, NodeType>::value ||
-                         llvm::is_base_of<clang::CXXConstructExpr,
+    hasArgument, unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
+  TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value ||
+                         llvm::is_base_of<CXXConstructExpr,
                                           NodeType>::value),
                          instantiated_with_wrong_types);
   return (N < Node.getNumArgs() &&
@@ -948,11 +1194,11 @@
 ///     Foo() : foo_(1) { }
 ///     int foo_;
 ///   };
-/// record(Has(Constructor(hasAnyConstructorInitializer(anything()))))
-///   Class matches Foo, hasAnyConstructorInitializer matches foo_(1)
-AST_MATCHER_P(clang::CXXConstructorDecl, hasAnyConstructorInitializer,
-              internal::Matcher<clang::CXXCtorInitializer>, InnerMatcher) {
-  for (clang::CXXConstructorDecl::init_const_iterator I = Node.init_begin();
+/// record(has(constructor(hasAnyConstructorInitializer(anything()))))
+///   record matches Foo, hasAnyConstructorInitializer matches foo_(1)
+AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
+              internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
+  for (CXXConstructorDecl::init_const_iterator I = Node.init_begin();
        I != Node.init_end(); ++I) {
     if (InnerMatcher.matches(**I, Finder, Builder)) {
       return true;
@@ -972,9 +1218,9 @@
 ///     forField(hasName("foo_"))))))
 ///   matches Foo
 /// with forField matching foo_
-AST_MATCHER_P(clang::CXXCtorInitializer, forField,
-              internal::Matcher<clang::FieldDecl>, InnerMatcher) {
-  const clang::FieldDecl *NodeAsDecl = Node.getMember();
+AST_MATCHER_P(CXXCtorInitializer, forField,
+              internal::Matcher<FieldDecl>, InnerMatcher) {
+  const FieldDecl *NodeAsDecl = Node.getMember();
   return (NodeAsDecl != NULL &&
       InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
 }
@@ -990,9 +1236,9 @@
 ///     withInitializer(integerLiteral(equals(1)))))))
 ///   matches Foo
 /// with withInitializer matching (1)
-AST_MATCHER_P(clang::CXXCtorInitializer, withInitializer,
-              internal::Matcher<clang::Expr>, InnerMatcher) {
-  const clang::Expr* NodeAsExpr = Node.getInit();
+AST_MATCHER_P(CXXCtorInitializer, withInitializer,
+              internal::Matcher<Expr>, InnerMatcher) {
+  const Expr* NodeAsExpr = Node.getInit();
   return (NodeAsExpr != NULL &&
       InnerMatcher.matches(*NodeAsExpr, Finder, Builder));
 }
@@ -1008,13 +1254,13 @@
 ///   };
 /// constructor(hasAnyConstructorInitializer(isWritten()))
 ///   will match Foo(int), but not Foo()
-AST_MATCHER(clang::CXXCtorInitializer, isWritten) {
+AST_MATCHER(CXXCtorInitializer, isWritten) {
   return Node.isWritten();
 }
 
 /// \brief Matches a constructor declaration that has been implicitly added
 /// by the compiler (eg. implicit default/copy constructors).
-AST_MATCHER(clang::CXXConstructorDecl, isImplicit) {
+AST_MATCHER(CXXConstructorDecl, isImplicit) {
   return Node.isImplicit();
 }
 
@@ -1027,10 +1273,10 @@
 ///   matches x(1, y, 42)
 /// with hasAnyArgument(...)
 ///   matching y
-AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, internal::Matcher<clang::Expr>,
+AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, internal::Matcher<Expr>,
                           InnerMatcher) {
-  TOOLING_COMPILE_ASSERT((llvm::is_base_of<clang::CallExpr, NodeType>::value ||
-                         llvm::is_base_of<clang::CXXConstructExpr,
+  TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value ||
+                         llvm::is_base_of<CXXConstructExpr,
                                           NodeType>::value),
                          instantiated_with_wrong_types);
   for (unsigned I = 0; I < Node.getNumArgs(); ++I) {
@@ -1050,8 +1296,8 @@
 ///   matches f(int x) {}
 /// with hasParameter(...)
 ///   matching int x
-AST_MATCHER_P2(clang::FunctionDecl, hasParameter,
-               unsigned, N, internal::Matcher<clang::ParmVarDecl>,
+AST_MATCHER_P2(FunctionDecl, hasParameter,
+               unsigned, N, internal::Matcher<ParmVarDecl>,
                InnerMatcher) {
   return (N < Node.getNumParams() &&
           InnerMatcher.matches(
@@ -1068,8 +1314,8 @@
 ///   matches f(int x, int y, int z) {}
 /// with hasAnyParameter(...)
 ///   matching int y
-AST_MATCHER_P(clang::FunctionDecl, hasAnyParameter,
-              internal::Matcher<clang::ParmVarDecl>, InnerMatcher) {
+AST_MATCHER_P(FunctionDecl, hasAnyParameter,
+              internal::Matcher<ParmVarDecl>, InnerMatcher) {
   for (unsigned I = 0; I < Node.getNumParams(); ++I) {
     if (InnerMatcher.matches(*Node.getParamDecl(I), Finder, Builder)) {
       return true;
@@ -1078,18 +1324,28 @@
   return false;
 }
 
+/// \brief Matches the return type of a function declaration.
+///
+/// Given:
+///   class X { int f() { return 1; } };
+/// method(returns(asString("int")))
+///   matches int f() { return 1; }
+AST_MATCHER_P(FunctionDecl, returns, internal::Matcher<QualType>, Matcher) {
+  return Matcher.matches(Node.getResultType(), Finder, Builder);
+}
+
 /// \brief 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, internal::Matcher<clang::Expr>,
+AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher<Expr>,
                           InnerMatcher) {
   TOOLING_COMPILE_ASSERT(
-    (llvm::is_base_of<clang::IfStmt, NodeType>::value) ||
-    (llvm::is_base_of<clang::ConditionalOperator, NodeType>::value),
+    (llvm::is_base_of<IfStmt, NodeType>::value) ||
+    (llvm::is_base_of<ConditionalOperator, NodeType>::value),
     has_condition_requires_if_statement_or_conditional_operator);
-  const clang::Expr *const Condition = Node.getCond();
+  const Expr *const Condition = Node.getCond();
   return (Condition != NULL &&
           InnerMatcher.matches(*Condition, Finder, Builder));
 }
@@ -1100,14 +1356,43 @@
 ///   if (A* a = GetAPointer()) {}
 /// hasConditionVariableStatment(...)
 ///   matches 'A* a = GetAPointer()'.
-AST_MATCHER_P(clang::IfStmt, hasConditionVariableStatement,
-              internal::Matcher<clang::DeclStmt>, InnerMatcher) {
-  const clang::DeclStmt* const DeclarationStatement =
+AST_MATCHER_P(IfStmt, hasConditionVariableStatement,
+              internal::Matcher<DeclStmt>, InnerMatcher) {
+  const DeclStmt* const DeclarationStatement =
     Node.getConditionVariableDeclStmt();
   return DeclarationStatement != NULL &&
          InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
 }
 
+/// \brief Matches the index expression of an array subscript expression.
+///
+/// Given
+///   int i[5];
+///   void f() { i[1] = 42; }
+/// arraySubscriptExpression(hasIndex(integerLiteral()))
+///   matches \c i[1] with the \c integerLiteral() matching \c 1
+AST_MATCHER_P(ArraySubscriptExpr, hasIndex,
+              internal::Matcher<Expr>, matcher) {
+  if (const Expr* Expression = Node.getIdx())
+    return matcher.matches(*Expression, Finder, Builder);
+  return false;
+}
+
+/// \brief Matches the base expression of an array subscript expression.
+///
+/// Given
+///   int i[5];
+///   void f() { i[1] = 42; }
+/// arraySubscriptExpression(hasBase(implicitCast(
+///     hasSourceExpression(declarationReference()))))
+///   matches \c i[1] with the \c declarationReference() matching \c i
+AST_MATCHER_P(ArraySubscriptExpr, hasBase,
+              internal::Matcher<Expr>, matcher) {
+  if (const Expr* Expression = Node.getBase())
+    return matcher.matches(*Expression, Finder, Builder);
+  return false;
+}
+
 /// \brief Matches a 'for' statement that has a given body.
 ///
 /// Given
@@ -1116,9 +1401,9 @@
 ///   matches 'for (;;) {}'
 /// with compoundStatement()
 ///   matching '{}'
-AST_MATCHER_P(clang::ForStmt, hasBody, internal::Matcher<clang::Stmt>,
+AST_MATCHER_P(ForStmt, hasBody, internal::Matcher<Stmt>,
               InnerMatcher) {
-  const clang::Stmt *const Statement = Node.getBody();
+  const Stmt *const Statement = Node.getBody();
   return (Statement != NULL &&
           InnerMatcher.matches(*Statement, Finder, Builder));
 }
@@ -1132,9 +1417,9 @@
 ///   matches '{ {}; 1+2; }'
 /// with compoundStatement()
 ///   matching '{}'
-AST_MATCHER_P(clang::CompoundStmt, hasAnySubstatement,
-              internal::Matcher<clang::Stmt>, InnerMatcher) {
-  for (clang::CompoundStmt::const_body_iterator It = Node.body_begin();
+AST_MATCHER_P(CompoundStmt, hasAnySubstatement,
+              internal::Matcher<Stmt>, InnerMatcher) {
+  for (CompoundStmt::const_body_iterator It = Node.body_begin();
        It != Node.body_end();
        ++It) {
     if (InnerMatcher.matches(**It, Finder, Builder)) return true;
@@ -1150,7 +1435,7 @@
 /// compoundStatement(statementCountIs(0)))
 ///   matches '{}'
 ///   but does not match the outer compound statement.
-AST_MATCHER_P(clang::CompoundStmt, statementCountIs, unsigned, N) {
+AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) {
   return Node.size() == N;
 }
 
@@ -1173,8 +1458,8 @@
 ///   !(a || b)
 AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) {
   TOOLING_COMPILE_ASSERT(
-    (llvm::is_base_of<clang::BinaryOperator, NodeType>::value) ||
-    (llvm::is_base_of<clang::UnaryOperator, NodeType>::value),
+    (llvm::is_base_of<BinaryOperator, NodeType>::value) ||
+    (llvm::is_base_of<UnaryOperator, NodeType>::value),
     has_condition_requires_if_statement_or_conditional_operator);
   return Name == Node.getOpcodeStr(Node.getOpcode());
 }
@@ -1183,9 +1468,9 @@
 ///
 /// Example matches a (matcher = binaryOperator(hasLHS()))
 ///   a || b
-AST_MATCHER_P(clang::BinaryOperator, hasLHS,
-              internal::Matcher<clang::Expr>, InnerMatcher) {
-  clang::Expr *LeftHandSide = Node.getLHS();
+AST_MATCHER_P(BinaryOperator, hasLHS,
+              internal::Matcher<Expr>, InnerMatcher) {
+  Expr *LeftHandSide = Node.getLHS();
   return (LeftHandSide != NULL &&
           InnerMatcher.matches(*LeftHandSide, Finder, Builder));
 }
@@ -1194,17 +1479,17 @@
 ///
 /// Example matches b (matcher = binaryOperator(hasRHS()))
 ///   a || b
-AST_MATCHER_P(clang::BinaryOperator, hasRHS,
-              internal::Matcher<clang::Expr>, InnerMatcher) {
-  clang::Expr *RightHandSide = Node.getRHS();
+AST_MATCHER_P(BinaryOperator, hasRHS,
+              internal::Matcher<Expr>, InnerMatcher) {
+  Expr *RightHandSide = Node.getRHS();
   return (RightHandSide != NULL &&
           InnerMatcher.matches(*RightHandSide, Finder, Builder));
 }
 
 /// \brief Matches if either the left hand side or the right hand side of a
 /// binary operator matches.
-inline internal::Matcher<clang::BinaryOperator> hasEitherOperand(
-    const internal::Matcher<clang::Expr> &InnerMatcher) {
+inline internal::Matcher<BinaryOperator> hasEitherOperand(
+    const internal::Matcher<Expr> &InnerMatcher) {
   return anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher));
 }
 
@@ -1212,23 +1497,24 @@
 ///
 /// Example matches true (matcher = hasOperand(boolLiteral(equals(true))))
 ///   !true
-AST_MATCHER_P(clang::UnaryOperator, hasUnaryOperand,
-              internal::Matcher<clang::Expr>, InnerMatcher) {
-  const clang::Expr * const Operand = Node.getSubExpr();
+AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
+              internal::Matcher<Expr>, InnerMatcher) {
+  const Expr * const Operand = Node.getSubExpr();
   return (Operand != NULL &&
           InnerMatcher.matches(*Operand, Finder, Builder));
 }
 
-/// Matches if the implicit cast's source expression matches the given matcher.
+/// \brief Matches if the implicit cast's source expression matches the given
+/// matcher.
 ///
 /// Example: matches "a string" (matcher =
 ///                                  hasSourceExpression(constructorCall()))
 ///
 /// class URL { URL(string); };
 /// URL url = "a string";
-AST_MATCHER_P(clang::ImplicitCastExpr, hasSourceExpression,
-              internal::Matcher<clang::Expr>, InnerMatcher) {
-  const clang::Expr* const SubExpression = Node.getSubExpr();
+AST_MATCHER_P(ImplicitCastExpr, hasSourceExpression,
+              internal::Matcher<Expr>, InnerMatcher) {
+  const Expr* const SubExpression = Node.getSubExpr();
   return (SubExpression != NULL &&
           InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
@@ -1237,9 +1523,9 @@
 ///
 /// (Note: Clang's AST refers to other conversions as "casts" too, and calls
 /// actual casts "explicit" casts.)
-AST_MATCHER_P(clang::ExplicitCastExpr, hasDestinationType,
-              internal::Matcher<clang::QualType>, InnerMatcher) {
-  const clang::QualType NodeType = Node.getTypeAsWritten();
+AST_MATCHER_P(ExplicitCastExpr, hasDestinationType,
+              internal::Matcher<QualType>, InnerMatcher) {
+  const QualType NodeType = Node.getTypeAsWritten();
   return InnerMatcher.matches(NodeType, Finder, Builder);
 }
 
@@ -1247,8 +1533,8 @@
 /// matcher.
 ///
 /// FIXME: Unit test this matcher
-AST_MATCHER_P(clang::ImplicitCastExpr, hasImplicitDestinationType,
-              internal::Matcher<clang::QualType>, InnerMatcher) {
+AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType,
+              internal::Matcher<QualType>, InnerMatcher) {
   return InnerMatcher.matches(Node.getType(), Finder, Builder);
 }
 
@@ -1256,9 +1542,9 @@
 ///
 /// Example matches a
 ///   condition ? a : b
-AST_MATCHER_P(clang::ConditionalOperator, hasTrueExpression,
-              internal::Matcher<clang::Expr>, InnerMatcher) {
-  clang::Expr *Expression = Node.getTrueExpr();
+AST_MATCHER_P(ConditionalOperator, hasTrueExpression,
+              internal::Matcher<Expr>, InnerMatcher) {
+  Expr *Expression = Node.getTrueExpr();
   return (Expression != NULL &&
           InnerMatcher.matches(*Expression, Finder, Builder));
 }
@@ -1267,9 +1553,9 @@
 ///
 /// Example matches b
 ///   condition ? a : b
-AST_MATCHER_P(clang::ConditionalOperator, hasFalseExpression,
-              internal::Matcher<clang::Expr>, InnerMatcher) {
-  clang::Expr *Expression = Node.getFalseExpr();
+AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
+              internal::Matcher<Expr>, InnerMatcher) {
+  Expr *Expression = Node.getFalseExpr();
   return (Expression != NULL &&
           InnerMatcher.matches(*Expression, Finder, Builder));
 }
@@ -1304,9 +1590,9 @@
 ///     A();
 ///   };
 ///   A a = A();
-AST_MATCHER_P(clang::CXXMethodDecl, ofClass,
-              internal::Matcher<clang::CXXRecordDecl>, InnerMatcher) {
-  const clang::CXXRecordDecl *Parent = Node.getParent();
+AST_MATCHER_P(CXXMethodDecl, ofClass,
+              internal::Matcher<CXXRecordDecl>, InnerMatcher) {
+  const CXXRecordDecl *Parent = Node.getParent();
   return (Parent != NULL &&
           InnerMatcher.matches(*Parent, Finder, Builder));
 }
@@ -1324,11 +1610,11 @@
 ///   };
 /// memberExpression(isArrow())
 ///   matches this->x, x, y.x, a, this->b
-inline internal::Matcher<clang::MemberExpr> isArrow() {
+inline internal::Matcher<MemberExpr> isArrow() {
   return makeMatcher(new internal::IsArrowMatcher());
 }
 
-/// \brief Matches clang::QualType nodes that are const-qualified, i.e., that
+/// \brief Matches QualType nodes that are const-qualified, i.e., that
 /// include "top-level" const.
 ///
 /// Given
@@ -1341,7 +1627,7 @@
 ///   matches "void b(int const)", "void c(const int)" and
 ///   "void e(int const) {}". It does not match d as there
 ///   is no top-level const on the parameter type "const int *".
-inline internal::Matcher<clang::QualType> isConstQualified() {
+inline internal::Matcher<QualType> isConstQualified() {
   return makeMatcher(new internal::IsConstQualifiedMatcher());
 }
 
@@ -1355,8 +1641,8 @@
 /// memberExpression(member(hasName("first")))
 ///   matches second.first
 ///   but not first.second (because the member name there is "second").
-AST_MATCHER_P(clang::MemberExpr, member,
-              internal::Matcher<clang::ValueDecl>, InnerMatcher) {
+AST_MATCHER_P(MemberExpr, member,
+              internal::Matcher<ValueDecl>, InnerMatcher) {
   return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
 }
 
@@ -1370,11 +1656,43 @@
 ///   matches "x.m" and "m"
 /// with hasObjectExpression(...)
 ///   matching "x" and the implicit object expression of "m" which has type X*.
-AST_MATCHER_P(clang::MemberExpr, hasObjectExpression,
-              internal::Matcher<clang::Expr>, InnerMatcher) {
+AST_MATCHER_P(MemberExpr, hasObjectExpression,
+              internal::Matcher<Expr>, InnerMatcher) {
   return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
 }
 
+/// \brief Matches any using shadow declaration.
+///
+/// Given
+///   namespace X { void b(); }
+///   using X::b;
+/// usingDecl(hasAnyUsingShadowDecl(hasName("b"))))
+///   matches \code using X::b \endcode
+AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl,
+              internal::Matcher<UsingShadowDecl>, Matcher) {
+  for (UsingDecl::shadow_iterator II = Node.shadow_begin();
+       II != Node.shadow_end(); ++II) {
+    if (Matcher.matches(**II, Finder, Builder))
+      return true;
+  }
+  return false;
+}
+
+/// \brief Matches a using shadow declaration where the target declaration is
+/// matched by the given matcher.
+///
+/// Given
+///   namespace X { int a; void b(); }
+///   using X::a;
+///   using X::b;
+/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(function())))
+///   matches \code using X::b \endcode
+///   but not \code using X::a \endcode
+AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
+              internal::Matcher<NamedDecl>, Matcher) {
+  return Matcher.matches(*Node.getTargetDecl(), Finder, Builder);
+}
+
 /// \brief Matches template instantiations of function, class, or static
 /// member variable template instantiations.
 ///

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=160013&r1=160012&r2=160013&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Tue Jul 10 15:20:19 2012
@@ -84,8 +84,8 @@
   BoundNodesTree();
 
   /// \brief Create a BoundNodesTree from pre-filled maps of bindings.
-  BoundNodesTree(const std::map<std::string, const clang::Decl*>& DeclBindings,
-                 const std::map<std::string, const clang::Stmt*>& StmtBindings,
+  BoundNodesTree(const std::map<std::string, const Decl*>& DeclBindings,
+                 const std::map<std::string, const Stmt*>& StmtBindings,
                  const std::vector<BoundNodesTree> RecursiveBindings);
 
   /// \brief Adds all bound nodes to bound_nodes_builder.
@@ -99,8 +99,8 @@
 private:
   void visitMatchesRecursively(
       Visitor* ResultVistior,
-      std::map<std::string, const clang::Decl*> DeclBindings,
-      std::map<std::string, const clang::Stmt*> StmtBindings);
+      std::map<std::string, const Decl*> DeclBindings,
+      std::map<std::string, const Stmt*> StmtBindings);
 
   template <typename T>
   void copyBindingsTo(const T& bindings, BoundNodesTreeBuilder* Builder) const;
@@ -108,8 +108,8 @@
   // FIXME: Find out whether we want to use different data structures here -
   // first benchmarks indicate that it doesn't matter though.
 
-  std::map<std::string, const clang::Decl*> DeclBindings;
-  std::map<std::string, const clang::Stmt*> StmtBindings;
+  std::map<std::string, const Decl*> DeclBindings;
+  std::map<std::string, const Stmt*> StmtBindings;
 
   std::vector<BoundNodesTree> RecursiveBindings;
 };
@@ -126,10 +126,8 @@
   ///
   /// FIXME: Add overloads for all AST base types.
   /// @{
-  void setBinding(const std::pair<const std::string,
-                                  const clang::Decl*>& binding);
-  void setBinding(const std::pair<const std::string,
-                                  const clang::Stmt*>& binding);
+  void setBinding(const std::string &Id, const Decl *Node);
+  void setBinding(const std::string &Id, const Stmt *Node);
   /// @}
 
   /// \brief Adds a branch in the tree.
@@ -142,8 +140,8 @@
   BoundNodesTreeBuilder(const BoundNodesTreeBuilder&);  // DO NOT IMPLEMENT
   void operator=(const BoundNodesTreeBuilder&);  // DO NOT IMPLEMENT
 
-  std::map<std::string, const clang::Decl*> DeclBindings;
-  std::map<std::string, const clang::Stmt*> StmtBindings;
+  std::map<std::string, const Decl*> DeclBindings;
+  std::map<std::string, const Stmt*> StmtBindings;
 
   std::vector<BoundNodesTree> RecursiveBindings;
 };
@@ -262,10 +260,10 @@
 template <typename T, typename DeclMatcherT>
 class HasDeclarationMatcher : public MatcherInterface<T> {
   TOOLING_COMPILE_ASSERT((llvm::is_same< DeclMatcherT,
-                                         Matcher<clang::Decl> >::value),
+                                         Matcher<Decl> >::value),
                           instantiated_with_wrong_types);
 public:
-  explicit HasDeclarationMatcher(const Matcher<clang::Decl> &InnerMatcher)
+  explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
       : InnerMatcher(InnerMatcher) {}
 
   virtual bool matches(const T &Node,
@@ -277,34 +275,36 @@
 private:
   /// \brief Extracts the CXXRecordDecl of a QualType and returns whether the
   /// inner matcher matches on it.
-  bool matchesSpecialized(const clang::QualType &Node, ASTMatchFinder *Finder,
+  bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
                           BoundNodesTreeBuilder *Builder) const {
     /// FIXME: Add other ways to convert...
-    clang::CXXRecordDecl *NodeAsRecordDecl = Node->getAsCXXRecordDecl();
+    if (Node.isNull())
+      return false;
+    CXXRecordDecl *NodeAsRecordDecl = Node->getAsCXXRecordDecl();
     return NodeAsRecordDecl != NULL &&
       InnerMatcher.matches(*NodeAsRecordDecl, Finder, Builder);
   }
 
   /// \brief 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,
+  bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,
                           BoundNodesTreeBuilder *Builder) const {
-    const clang::Decl *NodeAsDecl = Node.getCalleeDecl();
+    const Decl *NodeAsDecl = Node.getCalleeDecl();
     return NodeAsDecl != NULL &&
       InnerMatcher.matches(*NodeAsDecl, Finder, Builder);
   }
 
   /// \brief Extracts the Decl of the constructor call and returns whether the
   /// inner matcher matches on it.
-  bool matchesSpecialized(const clang::CXXConstructExpr &Node,
+  bool matchesSpecialized(const CXXConstructExpr &Node,
                           ASTMatchFinder *Finder,
                           BoundNodesTreeBuilder *Builder) const {
-    const clang::Decl *NodeAsDecl = Node.getConstructor();
+    const Decl *NodeAsDecl = Node.getConstructor();
     return NodeAsDecl != NULL &&
       InnerMatcher.matches(*NodeAsDecl, Finder, Builder);
   }
 
-  const Matcher<clang::Decl> InnerMatcher;
+  const Matcher<Decl> InnerMatcher;
 };
 
 /// \brief IsBaseType<T>::value is true if T is a "base" type in the AST
@@ -312,10 +312,10 @@
 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 ||
-       llvm::is_same<T, clang::CXXCtorInitializer>::value);
+      (llvm::is_same<T, Decl>::value ||
+       llvm::is_same<T, Stmt>::value ||
+       llvm::is_same<T, QualType>::value ||
+       llvm::is_same<T, CXXCtorInitializer>::value);
 };
 template <typename T>
 const bool IsBaseType<T>::value;
@@ -326,19 +326,19 @@
 public:
   virtual ~UntypedBaseMatcher() {}
 
-  virtual bool matches(const clang::Decl &DeclNode, ASTMatchFinder *Finder,
+  virtual bool matches(const Decl &DeclNode, ASTMatchFinder *Finder,
                        BoundNodesTreeBuilder *Builder) const {
     return false;
   }
-  virtual bool matches(const clang::QualType &TypeNode, ASTMatchFinder *Finder,
+  virtual bool matches(const QualType &TypeNode, ASTMatchFinder *Finder,
                        BoundNodesTreeBuilder *Builder) const {
     return false;
   }
-  virtual bool matches(const clang::Stmt &StmtNode, ASTMatchFinder *Finder,
+  virtual bool matches(const Stmt &StmtNode, ASTMatchFinder *Finder,
                        BoundNodesTreeBuilder *Builder) const {
     return false;
   }
-  virtual bool matches(const clang::CXXCtorInitializer &CtorInitNode,
+  virtual bool matches(const CXXCtorInitializer &CtorInitNode,
                        ASTMatchFinder *Finder,
                        BoundNodesTreeBuilder *Builder) const {
     return false;
@@ -414,26 +414,26 @@
   /// 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,
+  virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
                                   StringRef BaseName) const = 0;
 
   // FIXME: Implement for other base nodes.
-  virtual bool matchesChildOf(const clang::Decl &DeclNode,
+  virtual bool matchesChildOf(const Decl &DeclNode,
                               const UntypedBaseMatcher &BaseMatcher,
                               BoundNodesTreeBuilder *Builder,
                               TraversalKind Traverse,
                               BindKind Bind) = 0;
-  virtual bool matchesChildOf(const clang::Stmt &StmtNode,
+  virtual bool matchesChildOf(const Stmt &StmtNode,
                               const UntypedBaseMatcher &BaseMatcher,
                               BoundNodesTreeBuilder *Builder,
                               TraversalKind Traverse,
                               BindKind Bind) = 0;
 
-  virtual bool matchesDescendantOf(const clang::Decl &DeclNode,
+  virtual bool matchesDescendantOf(const Decl &DeclNode,
                                    const UntypedBaseMatcher &BaseMatcher,
                                    BoundNodesTreeBuilder *Builder,
                                    BindKind Bind) = 0;
-  virtual bool matchesDescendantOf(const clang::Stmt &StmtNode,
+  virtual bool matchesDescendantOf(const Stmt &StmtNode,
                                    const UntypedBaseMatcher &BaseMatcher,
                                    BoundNodesTreeBuilder *Builder,
                                    BindKind Bind) = 0;
@@ -566,17 +566,17 @@
   const Matcher<To> InnerMatcher;
 };
 
-/// \brief Enables the user to pass a Matcher<clang::CXXMemberCallExpr> to
+/// \brief Enables the user to pass a Matcher<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 {
+inline Matcher<CXXMemberCallExpr>::
+operator Matcher<CallExpr>() const {
   return makeMatcher(
-    new DynCastMatcher<clang::CallExpr, clang::CXXMemberCallExpr>(*this));
+    new DynCastMatcher<CallExpr, CXXMemberCallExpr>(*this));
 }
 
 /// \brief Matcher<T> that wraps an inner Matcher<T> and binds the matched node
@@ -594,7 +594,7 @@
                        BoundNodesTreeBuilder *Builder) const {
     bool Result = InnerMatcher.matches(Node, Finder, Builder);
     if (Result) {
-      Builder->setBinding(std::pair<const std::string, const T*>(ID, &Node));
+      Builder->setBinding(ID, &Node);
     }
     return Result;
   }
@@ -795,11 +795,11 @@
 /// the value the ValueEqualsMatcher was constructed with.
 template <typename T, typename ValueT>
 class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT((llvm::is_base_of<clang::CharacterLiteral, T>::value ||
-                         llvm::is_base_of<clang::CXXBoolLiteralExpr,
+  TOOLING_COMPILE_ASSERT((llvm::is_base_of<CharacterLiteral, T>::value ||
+                         llvm::is_base_of<CXXBoolLiteralExpr,
                                           T>::value ||
-                         llvm::is_base_of<clang::FloatingLiteral, T>::value ||
-                         llvm::is_base_of<clang::IntegerLiteral, T>::value),
+                         llvm::is_base_of<FloatingLiteral, T>::value ||
+                         llvm::is_base_of<IntegerLiteral, T>::value),
                          the_node_must_have_a_getValue_method);
 public:
   explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
@@ -816,9 +816,9 @@
 template <typename T>
 class IsDefinitionMatcher : public SingleNodeMatcherInterface<T> {
   TOOLING_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),
+    (llvm::is_base_of<TagDecl, T>::value) ||
+    (llvm::is_base_of<VarDecl, T>::value) ||
+    (llvm::is_base_of<FunctionDecl, T>::value),
     is_definition_requires_isThisDeclarationADefinition_method);
 public:
   virtual bool matchesNode(const T &Node) const {
@@ -830,32 +830,32 @@
 /// CXXRecordDecl nodes.
 template <typename T>
 class IsTemplateInstantiationMatcher : public MatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT((llvm::is_base_of<clang::FunctionDecl, T>::value) ||
-                         (llvm::is_base_of<clang::VarDecl, T>::value) ||
-                         (llvm::is_base_of<clang::CXXRecordDecl, T>::value),
+  TOOLING_COMPILE_ASSERT((llvm::is_base_of<FunctionDecl, T>::value) ||
+                         (llvm::is_base_of<VarDecl, T>::value) ||
+                         (llvm::is_base_of<CXXRecordDecl, T>::value),
                          requires_getTemplateSpecializationKind_method);
  public:
   virtual bool matches(const T& Node,
                        ASTMatchFinder* Finder,
                        BoundNodesTreeBuilder* Builder) const {
     return (Node.getTemplateSpecializationKind() ==
-                clang::TSK_ImplicitInstantiation ||
+                TSK_ImplicitInstantiation ||
             Node.getTemplateSpecializationKind() ==
-                clang::TSK_ExplicitInstantiationDefinition);
+                TSK_ExplicitInstantiationDefinition);
   }
 };
 
-class IsArrowMatcher : public SingleNodeMatcherInterface<clang::MemberExpr> {
+class IsArrowMatcher : public SingleNodeMatcherInterface<MemberExpr> {
 public:
-  virtual bool matchesNode(const clang::MemberExpr &Node) const {
+  virtual bool matchesNode(const MemberExpr &Node) const {
     return Node.isArrow();
   }
 };
 
 class IsConstQualifiedMatcher
-    : public SingleNodeMatcherInterface<clang::QualType> {
+    : public SingleNodeMatcherInterface<QualType> {
  public:
-  virtual bool matchesNode(const clang::QualType& Node) const {
+  virtual bool matchesNode(const QualType& Node) const {
     return Node.isConstQualified();
   }
 };
@@ -867,11 +867,11 @@
 ///
 /// For example:
 ///   const VariadicDynCastAllOfMatcher<
-///       clang::Decl, clang::CXXRecordDecl> record;
-/// Creates a functor record(...) that creates a Matcher<clang::Decl> given
-/// a variable number of arguments of type Matcher<clang::CXXRecordDecl>.
-/// The returned matcher matches if the given clang::Decl can by dynamically
-/// casted to clang::CXXRecordDecl and all given matchers match.
+///       Decl, CXXRecordDecl> record;
+/// Creates a functor record(...) that creates a Matcher<Decl> given
+/// a variable number of arguments of type Matcher<CXXRecordDecl>.
+/// The returned matcher matches if the given Decl can by dynamically
+/// casted to CXXRecordDecl and all given matchers match.
 template <typename SourceT, typename TargetT>
 class VariadicDynCastAllOfMatcher
     : public llvm::VariadicFunction<

Modified: cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp?rev=160013&r1=160012&r2=160013&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp Tue Jul 10 15:20:19 2012
@@ -51,9 +51,9 @@
 // A RecursiveASTVisitor that traverses all children or all descendants of
 // a node.
 class MatchChildASTVisitor
-    : public clang::RecursiveASTVisitor<MatchChildASTVisitor> {
+    : public RecursiveASTVisitor<MatchChildASTVisitor> {
 public:
-  typedef clang::RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase;
+  typedef 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
@@ -95,21 +95,21 @@
   // 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) {
+  bool TraverseDecl(Decl *DeclNode) {
     return (DeclNode == NULL) || traverse(*DeclNode);
   }
-  bool TraverseStmt(clang::Stmt *StmtNode) {
-    const clang::Stmt *StmtToTraverse = StmtNode;
+  bool TraverseStmt(Stmt *StmtNode) {
+    const Stmt *StmtToTraverse = StmtNode;
     if (Traversal ==
         ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses) {
-      const clang::Expr *ExprNode = dyn_cast_or_null<clang::Expr>(StmtNode);
+      const Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode);
       if (ExprNode != NULL) {
         StmtToTraverse = ExprNode->IgnoreParenImpCasts();
       }
     }
     return (StmtToTraverse == NULL) || traverse(*StmtToTraverse);
   }
-  bool TraverseType(clang::QualType TypeNode) {
+  bool TraverseType(QualType TypeNode) {
     return traverse(TypeNode);
   }
 
@@ -134,13 +134,13 @@
 
   // 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 Decl &DeclNode) {
+    return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode));
   }
-  bool baseTraverse(const clang::Stmt &StmtNode) {
-    return VisitorBase::TraverseStmt(const_cast<clang::Stmt*>(&StmtNode));
+  bool baseTraverse(const Stmt &StmtNode) {
+    return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode));
   }
-  bool baseTraverse(clang::QualType TypeNode) {
+  bool baseTraverse(QualType TypeNode) {
     return VisitorBase::TraverseType(TypeNode);
   }
 
@@ -197,7 +197,7 @@
 
 // Controls the outermost traversal of the AST and allows to match multiple
 // matchers.
-class MatchASTVisitor : public clang::RecursiveASTVisitor<MatchASTVisitor>,
+class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
                         public ASTMatchFinder {
 public:
   MatchASTVisitor(std::vector< std::pair<const UntypedBaseMatcher*,
@@ -206,14 +206,14 @@
        ActiveASTContext(NULL) {
   }
 
-  void set_active_ast_context(clang::ASTContext *NewActiveASTContext) {
+  void set_active_ast_context(ASTContext *NewActiveASTContext) {
     ActiveASTContext = NewActiveASTContext;
   }
 
   // The following Visit*() and Traverse*() functions "override"
   // methods in RecursiveASTVisitor.
 
-  bool VisitTypedefDecl(clang::TypedefDecl *DeclNode) {
+  bool VisitTypedefDecl(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
@@ -241,18 +241,18 @@
     // 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
+    const Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr();
+    const 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);
+  bool TraverseDecl(Decl *DeclNode);
+  bool TraverseStmt(Stmt *StmtNode);
+  bool TraverseType(QualType TypeNode);
+  bool TraverseTypeLoc(TypeLoc TypeNode);
 
   // Matches children or descendants of 'Node' with 'BaseMatcher'.
   template <typename T>
@@ -260,8 +260,8 @@
                                   const UntypedBaseMatcher &BaseMatcher,
                                   BoundNodesTreeBuilder *Builder, int MaxDepth,
                                   TraversalKind Traversal, BindKind Bind) {
-    TOOLING_COMPILE_ASSERT((llvm::is_same<T, clang::Decl>::value) ||
-                           (llvm::is_same<T, clang::Stmt>::value),
+    TOOLING_COMPILE_ASSERT((llvm::is_same<T, Decl>::value) ||
+                           (llvm::is_same<T, Stmt>::value),
                            type_does_not_support_memoization);
     const UntypedMatchInput input(BaseMatcher.getID(), &Node);
     std::pair<MemoizationMap::iterator, bool> InsertResult
@@ -288,11 +288,11 @@
     return Visitor.findMatch(Node);
   }
 
-  virtual bool classIsDerivedFrom(const clang::CXXRecordDecl *Declaration,
+  virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
                                   StringRef BaseName) const;
 
   // Implements ASTMatchFinder::MatchesChildOf.
-  virtual bool matchesChildOf(const clang::Decl &DeclNode,
+  virtual bool matchesChildOf(const Decl &DeclNode,
                               const UntypedBaseMatcher &BaseMatcher,
                               BoundNodesTreeBuilder *Builder,
                               TraversalKind Traversal,
@@ -300,7 +300,7 @@
     return matchesRecursively(DeclNode, BaseMatcher, Builder, 1, Traversal,
                               Bind);
   }
-  virtual bool matchesChildOf(const clang::Stmt &StmtNode,
+  virtual bool matchesChildOf(const Stmt &StmtNode,
                               const UntypedBaseMatcher &BaseMatcher,
                               BoundNodesTreeBuilder *Builder,
                               TraversalKind Traversal,
@@ -310,14 +310,14 @@
   }
 
   // Implements ASTMatchFinder::MatchesDescendantOf.
-  virtual bool matchesDescendantOf(const clang::Decl &DeclNode,
+  virtual bool matchesDescendantOf(const Decl &DeclNode,
                                    const UntypedBaseMatcher &BaseMatcher,
                                    BoundNodesTreeBuilder *Builder,
                                    BindKind Bind) {
     return memoizedMatchesRecursively(DeclNode, BaseMatcher, Builder, INT_MAX,
                                       TK_AsIs, Bind);
   }
-  virtual bool matchesDescendantOf(const clang::Stmt &StmtNode,
+  virtual bool matchesDescendantOf(const Stmt &StmtNode,
                                    const UntypedBaseMatcher &BaseMatcher,
                                    BoundNodesTreeBuilder *Builder,
                                    BindKind Bind) {
@@ -333,7 +333,7 @@
   // the aggregated bound nodes for each match.
   class MatchVisitor : public BoundNodesTree::Visitor {
   public:
-    MatchVisitor(clang::ASTContext* Context,
+    MatchVisitor(ASTContext* Context,
                  MatchFinder::MatchCallback* Callback)
       : Context(Context),
         Callback(Callback) {}
@@ -343,16 +343,16 @@
     }
 
   private:
-    clang::ASTContext* Context;
+    ASTContext* Context;
     MatchFinder::MatchCallback* Callback;
   };
 
   // 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,
+  bool typeHasAlias(const Type *TypeNode,
                     StringRef Name) const {
-    const clang::Type *const CanonicalType =
+    const Type *const CanonicalType =
       ActiveASTContext->getCanonicalType(TypeNode);
     const std::set<std::string> *UnqualifiedAlias =
       find(TypeToUnqualifiedAliases, CanonicalType);
@@ -378,10 +378,10 @@
 
   std::vector< std::pair<const UntypedBaseMatcher*,
                MatchFinder::MatchCallback*> > *const Triggers;
-  clang::ASTContext *ActiveASTContext;
+  ASTContext *ActiveASTContext;
 
   // Maps a canonical type to the names of its typedefs.
-  llvm::DenseMap<const clang::Type*, std::set<std::string> >
+  llvm::DenseMap<const Type*, std::set<std::string> >
     TypeToUnqualifiedAliases;
 
   // Maps (matcher, node) -> the match result for memoization.
@@ -393,7 +393,7 @@
 // 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,
+MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration,
                                     StringRef BaseName) const {
   if (Declaration->getName() == BaseName) {
     return true;
@@ -401,24 +401,24 @@
   if (!Declaration->hasDefinition()) {
     return false;
   }
-  typedef clang::CXXRecordDecl::base_class_const_iterator BaseIterator;
+  typedef 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();
+    const 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) {
+    // Type::getAs<...>() drills through typedefs.
+    if (TypeNode->getAs<DependentNameType>() != NULL ||
+        TypeNode->getAs<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>();
+    CXXRecordDecl *ClassDecl = NULL;
+    TemplateSpecializationType const *TemplateType =
+      TypeNode->getAs<TemplateSpecializationType>();
     if (TemplateType != NULL) {
       if (TemplateType->getTemplateName().isDependent()) {
         // Dependent template specializations will be matched when the
@@ -434,12 +434,12 @@
       // 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 =
+      CXXRecordDecl *SpecializationDecl =
         TemplateType->getAsCXXRecordDecl();
       if (SpecializationDecl != NULL) {
         ClassDecl = SpecializationDecl;
       } else {
-        ClassDecl = llvm::dyn_cast<clang::CXXRecordDecl>(
+        ClassDecl = llvm::dyn_cast<CXXRecordDecl>(
             TemplateType->getTemplateName()
                 .getAsTemplateDecl()->getTemplatedDecl());
       }
@@ -455,33 +455,33 @@
   return false;
 }
 
-bool MatchASTVisitor::TraverseDecl(clang::Decl *DeclNode) {
+bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) {
   if (DeclNode == NULL) {
     return true;
   }
   match(*DeclNode);
-  return clang::RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode);
+  return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode);
 }
 
-bool MatchASTVisitor::TraverseStmt(clang::Stmt *StmtNode) {
+bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode) {
   if (StmtNode == NULL) {
     return true;
   }
   match(*StmtNode);
-  return clang::RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode);
+  return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode);
 }
 
-bool MatchASTVisitor::TraverseType(clang::QualType TypeNode) {
+bool MatchASTVisitor::TraverseType(QualType TypeNode) {
   match(TypeNode);
-  return clang::RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode);
+  return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode);
 }
 
-bool MatchASTVisitor::TraverseTypeLoc(clang::TypeLoc TypeLoc) {
-  return clang::RecursiveASTVisitor<MatchASTVisitor>::
+bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLoc) {
+  return RecursiveASTVisitor<MatchASTVisitor>::
       TraverseType(TypeLoc.getType());
 }
 
-class MatchASTConsumer : public clang::ASTConsumer {
+class MatchASTConsumer : public ASTConsumer {
 public:
   MatchASTConsumer(std::vector< std::pair<const UntypedBaseMatcher*,
                                 MatchFinder::MatchCallback*> > *Triggers,
@@ -490,7 +490,7 @@
         ParsingDone(ParsingDone) {}
 
 private:
-  virtual void HandleTranslationUnit(clang::ASTContext &Context) {
+  virtual void HandleTranslationUnit(ASTContext &Context) {
     if (ParsingDone != NULL) {
       ParsingDone->run();
     }
@@ -507,7 +507,7 @@
 } // end namespace internal
 
 MatchFinder::MatchResult::MatchResult(const BoundNodes &Nodes,
-                                      clang::ASTContext *Context)
+                                      ASTContext *Context)
   : Nodes(Nodes), Context(Context),
     SourceManager(&Context->getSourceManager()) {}
 
@@ -528,22 +528,22 @@
 void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch,
                              MatchCallback *Action) {
   Triggers.push_back(std::make_pair(
-    new internal::TypedBaseMatcher<clang::Decl>(NodeMatch), Action));
+    new internal::TypedBaseMatcher<Decl>(NodeMatch), Action));
 }
 
 void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,
                              MatchCallback *Action) {
   Triggers.push_back(std::make_pair(
-    new internal::TypedBaseMatcher<clang::QualType>(NodeMatch), Action));
+    new internal::TypedBaseMatcher<QualType>(NodeMatch), Action));
 }
 
 void MatchFinder::addMatcher(const StatementMatcher &NodeMatch,
                              MatchCallback *Action) {
   Triggers.push_back(std::make_pair(
-    new internal::TypedBaseMatcher<clang::Stmt>(NodeMatch), Action));
+    new internal::TypedBaseMatcher<Stmt>(NodeMatch), Action));
 }
 
-clang::ASTConsumer *MatchFinder::newASTConsumer() {
+ASTConsumer *MatchFinder::newASTConsumer() {
   return new internal::MatchASTConsumer(&Triggers, ParsingDone);
 }
 

Modified: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=160013&r1=160012&r2=160013&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Tue Jul 10 15:20:19 2012
@@ -21,8 +21,8 @@
 BoundNodesTree::BoundNodesTree() {}
 
 BoundNodesTree::BoundNodesTree(
-  const std::map<std::string, const clang::Decl*>& DeclBindings,
-  const std::map<std::string, const clang::Stmt*>& StmtBindings,
+  const std::map<std::string, const Decl*>& DeclBindings,
+  const std::map<std::string, const Stmt*>& StmtBindings,
   const std::vector<BoundNodesTree> RecursiveBindings)
   : DeclBindings(DeclBindings), StmtBindings(StmtBindings),
     RecursiveBindings(RecursiveBindings) {}
@@ -44,22 +44,22 @@
   for (typename T::const_iterator I = Bindings.begin(),
                                   E = Bindings.end();
        I != E; ++I) {
-    Builder->setBinding(*I);
+    Builder->setBinding(I->first, I->second);
   }
 }
 
 void BoundNodesTree::visitMatches(Visitor* ResultVisitor) {
-  std::map<std::string, const clang::Decl*> AggregatedDeclBindings;
-  std::map<std::string, const clang::Stmt*> AggregatedStmtBindings;
+  std::map<std::string, const Decl*> AggregatedDeclBindings;
+  std::map<std::string, const Stmt*> AggregatedStmtBindings;
   visitMatchesRecursively(ResultVisitor, AggregatedDeclBindings,
                           AggregatedStmtBindings);
 }
 
 void BoundNodesTree::
 visitMatchesRecursively(Visitor* ResultVisitor,
-                        std::map<std::string, const clang::Decl*>
+                        std::map<std::string, const Decl*>
                           AggregatedDeclBindings,
-                        std::map<std::string, const clang::Stmt*>
+                        std::map<std::string, const Stmt*>
                           AggregatedStmtBindings) {
   copy(DeclBindings.begin(), DeclBindings.end(),
        inserter(AggregatedDeclBindings, AggregatedDeclBindings.begin()));
@@ -79,14 +79,14 @@
 
 BoundNodesTreeBuilder::BoundNodesTreeBuilder() {}
 
-void BoundNodesTreeBuilder::
-setBinding(const std::pair<const std::string, const clang::Decl*>& Binding) {
-  DeclBindings.insert(Binding);
+void BoundNodesTreeBuilder::setBinding(const std::string &Id,
+                                       const Decl *Node) {
+  DeclBindings[Id] = Node;
 }
 
-void BoundNodesTreeBuilder::
-setBinding(const std::pair<const std::string, const clang::Stmt*>& Binding) {
-  StmtBindings.insert(Binding);
+void BoundNodesTreeBuilder::setBinding(const std::string &Id,
+                                       const Stmt *Node) {
+  StmtBindings[Id] = Node;
 }
 
 void BoundNodesTreeBuilder::addMatch(const BoundNodesTree& Bindings) {

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=160013&r1=160012&r2=160013&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Tue Jul 10 15:20:19 2012
@@ -24,6 +24,13 @@
   }, "");
 }
 
+TEST(HasNameDeathTest, DiesOnEmptyPattern) {
+  ASSERT_DEBUG_DEATH({
+      DeclarationMatcher HasEmptyName = record(matchesName(""));
+      EXPECT_TRUE(notMatches("class X {};", HasEmptyName));
+    }, "");
+}
+
 TEST(IsDerivedFromDeathTest, DiesOnEmptyBaseName) {
   ASSERT_DEBUG_DEATH({
     DeclarationMatcher IsDerivedFromEmpty = record(isDerivedFrom(""));
@@ -40,10 +47,34 @@
   EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX));
   EXPECT_TRUE(matches("void foo() { int X; }", NamedX));
   EXPECT_TRUE(matches("namespace X { }", NamedX));
+  EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
 
   EXPECT_TRUE(notMatches("#define X 1", NamedX));
 }
 
+TEST(NameableDeclaration, REMatchesVariousDecls) {
+  DeclarationMatcher NamedX = nameableDeclaration(matchesName("::X"));
+  EXPECT_TRUE(matches("typedef int Xa;", NamedX));
+  EXPECT_TRUE(matches("int Xb;", NamedX));
+  EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX));
+  EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX));
+  EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX));
+  EXPECT_TRUE(matches("namespace Xij { }", NamedX));
+  EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
+
+  EXPECT_TRUE(notMatches("#define Xkl 1", NamedX));
+
+  DeclarationMatcher StartsWithNo = nameableDeclaration(matchesName("::no"));
+  EXPECT_TRUE(matches("int no_foo;", StartsWithNo));
+  EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo));
+
+  DeclarationMatcher Abc = nameableDeclaration(matchesName("a.*b.*c"));
+  EXPECT_TRUE(matches("int abc;", Abc));
+  EXPECT_TRUE(matches("int aFOObBARc;", Abc));
+  EXPECT_TRUE(notMatches("int cab;", Abc));
+  EXPECT_TRUE(matches("int cabc;", Abc));
+}
+
 TEST(DeclarationMatcher, MatchClass) {
   DeclarationMatcher ClassMatcher(record());
 #if !defined(_MSC_VER)
@@ -456,6 +487,21 @@
       "};", ZDescendantClassXDescendantClassY));
 }
 
+TEST(Enum, DoesNotMatchClasses) {
+  EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
+}
+
+TEST(Enum, MatchesEnums) {
+  EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
+}
+
+TEST(EnumConstant, Matches) {
+  DeclarationMatcher Matcher = enumConstant(hasName("A"));
+  EXPECT_TRUE(matches("enum X{ A };", Matcher));
+  EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
+  EXPECT_TRUE(notMatches("enum X {};", Matcher));
+}
+
 TEST(StatementMatcher, Has) {
   StatementMatcher HasVariableI =
       expression(
@@ -552,23 +598,40 @@
   DeclarationMatcher ClassX = has(id("x", record(hasName("X"))));
 
   EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
-      ClassX, new VerifyIdIsBoundToDecl<clang::CXXRecordDecl>("x")));
+      ClassX, new VerifyIdIsBoundToDecl<CXXRecordDecl>("x")));
 
   EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
-      ClassX, new VerifyIdIsBoundToDecl<clang::CXXRecordDecl>("other-id")));
+      ClassX, new VerifyIdIsBoundToDecl<CXXRecordDecl>("other-id")));
 
   TypeMatcher TypeAHasClassB = hasDeclaration(
       record(hasName("A"), has(id("b", record(hasName("B"))))));
 
   EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
       TypeAHasClassB,
-      new VerifyIdIsBoundToDecl<clang::Decl>("b")));
+      new VerifyIdIsBoundToDecl<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")));
+      new VerifyIdIsBoundToStmt<CXXMemberCallExpr>("x")));
+}
+
+TEST(Matcher, BindTheSameNameInAlternatives) {
+  StatementMatcher matcher = anyOf(
+      binaryOperator(hasOperatorName("+"),
+                     hasLHS(id("x", expression())),
+                     hasRHS(integerLiteral(equals(0)))),
+      binaryOperator(hasOperatorName("+"),
+                     hasLHS(integerLiteral(equals(0))),
+                     hasRHS(id("x", expression()))));
+
+  EXPECT_TRUE(matchAndVerifyResultTrue(
+      // The first branch of the matcher binds x to 0 but then fails.
+      // The second branch binds x to f() and succeeds.
+      "int f() { return 0 + f(); }",
+      matcher,
+      new VerifyIdIsBoundToStmt<CallExpr>("x")));
 }
 
 TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
@@ -613,7 +676,7 @@
 
 TEST(Matcher, Call) {
   // FIXME: Do we want to overload Call() to directly take
-  // Matcher<clang::Decl>, too?
+  // Matcher<Decl>, too?
   StatementMatcher MethodX = call(hasDeclaration(method(hasName("x"))));
 
   EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
@@ -657,6 +720,18 @@
                  MethodOnYPointer));
 }
 
+TEST(HasType, MatchesAsString) {
+  EXPECT_TRUE(
+      matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
+              call(on(hasType(asString("class Y *"))))));
+  EXPECT_TRUE(matches("class X { void x(int x) {} };",
+      method(hasParameter(0, hasType(asString("int"))))));
+  EXPECT_TRUE(matches("namespace ns { struct A {}; }  struct B { ns::A a; };",
+      field(hasType(asString("ns::A")))));
+  EXPECT_TRUE(matches("namespace { struct A {}; }  struct B { A a; };",
+      field(hasType(asString("struct <anonymous>::A")))));
+}
+
 TEST(Matcher, OverloadedOperatorCall) {
   StatementMatcher OpCall = overloadedOperatorCall();
   // Unary operator
@@ -772,6 +847,30 @@
       CallOnVariableY));
 }
 
+TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
+  EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
+                      unaryExprOrTypeTraitExpr()));
+  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
+                         alignOfExpr(anything())));
+  // FIXME: Uncomment once alignof is enabled.
+  // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
+  //                     unaryExprOrTypeTraitExpr()));
+  // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
+  //                        sizeOfExpr()));
+}
+
+TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
+  EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
+      hasArgumentOfType(asString("int")))));
+  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
+      hasArgumentOfType(asString("float")))));
+  EXPECT_TRUE(matches(
+      "struct A {}; void x() { A a; int b = sizeof(a); }",
+      sizeOfExpr(hasArgumentOfType(hasDeclaration(record(hasName("A")))))));
+  EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
+      hasArgumentOfType(hasDeclaration(record(hasName("string")))))));
+}
+
 TEST(MemberExpression, DoesNotMatchClasses) {
   EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpression()));
 }
@@ -939,6 +1038,15 @@
       method(hasAnyParameter(hasType(record(hasName("X")))))));
 }
 
+TEST(Returns, MatchesReturnTypes) {
+  EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
+                      function(returns(asString("int")))));
+  EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
+                         function(returns(asString("float")))));
+  EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
+                      function(returns(hasDeclaration(record(hasName("Y")))))));
+}
+
 TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
   EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
       method(hasAnyParameter(hasType(record(hasName("X")))))));
@@ -1062,6 +1170,15 @@
                       constructor(unless(isImplicit()))));
 }
 
+TEST(DestructorDeclaration, MatchesVirtualDestructor) {
+  EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
+                      destructor(ofClass(hasName("Foo")))));
+}
+
+TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
+  EXPECT_TRUE(notMatches("class Foo {};", destructor(ofClass(hasName("Foo")))));
+}
+
 TEST(HasAnyConstructorInitializer, SimpleCase) {
   EXPECT_TRUE(notMatches(
       "class Foo { Foo() { } };",
@@ -1162,6 +1279,11 @@
                  New));
 }
 
+TEST(Matcher, DeleteExpression) {
+  EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
+                      deleteExpression()));
+}
+
 TEST(Matcher, DefaultArgument) {
   StatementMatcher Arg = defaultArgument();
 
@@ -1412,6 +1534,32 @@
       notMatches("void x() { true ? false : true; }", ConditionalFalse));
 }
 
+TEST(ArraySubscriptMatchers, ArraySubscripts) {
+  EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
+                      arraySubscriptExpr()));
+  EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
+                         arraySubscriptExpr()));
+}
+
+TEST(ArraySubscriptMatchers, ArrayIndex) {
+  EXPECT_TRUE(matches(
+      "int i[2]; void f() { i[1] = 1; }",
+      arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
+  EXPECT_TRUE(matches(
+      "int i[2]; void f() { 1[i] = 1; }",
+      arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
+  EXPECT_TRUE(notMatches(
+      "int i[2]; void f() { i[1] = 1; }",
+      arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
+}
+
+TEST(ArraySubscriptMatchers, MatchesArrayBase) {
+  EXPECT_TRUE(matches(
+      "int i[2]; void f() { i[1] = 2; }",
+      arraySubscriptExpr(hasBase(implicitCast(
+          hasSourceExpression(declarationReference()))))));
+}
+
 TEST(Matcher, HasNameSupportsNamespaces) {
   EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
               record(hasName("a::b::C"))));
@@ -1519,8 +1667,33 @@
                  hasDescendant(call(callee(method(hasName("x"))))))));
 }
 
+TEST(Matcher, HandlesNullQualTypes) {
+  // FIXME: Add a Type matcher so we can replace uses of this
+  // variable with Type(True())
+  const TypeMatcher AnyType = anything();
+
+  // We don't really care whether this matcher succeeds; we're testing that
+  // it completes without crashing.
+  EXPECT_TRUE(matches(
+      "struct A { };"
+      "template <typename T>"
+      "void f(T t) {"
+      "  T local_t(t /* this becomes a null QualType in the AST */);"
+      "}"
+      "void g() {"
+      "  f(0);"
+      "}",
+      expression(hasType(TypeMatcher(
+          anyOf(
+              TypeMatcher(hasDeclaration(anything())),
+              pointsTo(AnyType),
+              references(AnyType)
+              // Other QualType matchers should go here.
+                ))))));
+}
+
 // For testing AST_MATCHER_P().
-AST_MATCHER_P(clang::Decl, just, internal::Matcher<clang::Decl>, AMatcher) {
+AST_MATCHER_P(Decl, just, internal::Matcher<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);
@@ -1530,21 +1703,21 @@
   DeclarationMatcher HasClassB = just(has(id("b", record(hasName("B")))));
 
   EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
-      HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("b")));
+      HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
 
   EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
-      HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("a")));
+      HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
 
   EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
-      HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("b")));
+      HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
 }
 
 AST_POLYMORPHIC_MATCHER_P(
-    polymorphicHas, internal::Matcher<clang::Decl>, AMatcher) {
-  TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, clang::Decl>::value) ||
-                         (llvm::is_same<NodeType, clang::Stmt>::value),
+    polymorphicHas, internal::Matcher<Decl>, AMatcher) {
+  TOOLING_COMPILE_ASSERT((llvm::is_same<NodeType, Decl>::value) ||
+                         (llvm::is_same<NodeType, Stmt>::value),
                          assert_node_type_is_accessible);
-  internal::TypedBaseMatcher<clang::Decl> ChildMatcher(AMatcher);
+  internal::TypedBaseMatcher<Decl> ChildMatcher(AMatcher);
   return Finder->matchesChildOf(
       Node, ChildMatcher, Builder,
       ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
@@ -1555,13 +1728,13 @@
   DeclarationMatcher HasClassB = polymorphicHas(id("b", record(hasName("B"))));
 
   EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
-      HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("b")));
+      HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
 
   EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
-      HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("a")));
+      HasClassB, new VerifyIdIsBoundToDecl<Decl>("a")));
 
   EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
-      HasClassB, new VerifyIdIsBoundToDecl<clang::Decl>("b")));
+      HasClassB, new VerifyIdIsBoundToDecl<Decl>("b")));
 
   StatementMatcher StatementHasClassB =
       polymorphicHas(record(hasName("B")));
@@ -1831,6 +2004,41 @@
   EXPECT_TRUE(matches("void x() { int a; }", declarationStatement()));
 }
 
+TEST(InitListExpression, MatchesInitListExpression) {
+  EXPECT_TRUE(matches("int a[] = { 1, 2 };",
+                      initListExpr(hasType(asString("int [2]")))));
+  EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
+                      initListExpr(hasType(record(hasName("B"))))));
+}
+
+TEST(UsingDeclaration, MatchesUsingDeclarations) {
+  EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
+                      usingDecl()));
+}
+
+TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
+  EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
+                      usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
+}
+
+TEST(UsingDeclaration, MatchesSpecificTarget) {
+  EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
+                      usingDecl(hasAnyUsingShadowDecl(
+                          hasTargetDecl(function())))));
+  EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
+                         usingDecl(hasAnyUsingShadowDecl(
+                             hasTargetDecl(function())))));
+}
+
+TEST(UsingDeclaration, ThroughUsingDeclaration) {
+  EXPECT_TRUE(matches(
+      "namespace a { void f(); } using a::f; void g() { f(); }",
+      declarationReference(throughUsingDecl(anything()))));
+  EXPECT_TRUE(notMatches(
+      "namespace a { void f(); } using a::f; void g() { a::f(); }",
+      declarationReference(throughUsingDecl(anything()))));
+}
+
 TEST(While, MatchesWhileLoops) {
   EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
   EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
@@ -1871,26 +2079,26 @@
 TEST(ForEach, BindsOneNode) {
   EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
       record(hasName("C"), forEach(id("x", field(hasName("x"))))),
-      new VerifyIdIsBoundToDecl<clang::FieldDecl>("x", 1)));
+      new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
 }
 
 TEST(ForEach, BindsMultipleNodes) {
   EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
       record(hasName("C"), forEach(id("f", field()))),
-      new VerifyIdIsBoundToDecl<clang::FieldDecl>("f", 3)));
+      new VerifyIdIsBoundToDecl<FieldDecl>("f", 3)));
 }
 
 TEST(ForEach, BindsRecursiveCombinations) {
   EXPECT_TRUE(matchAndVerifyResultTrue(
       "class C { class D { int x; int y; }; class E { int y; int z; }; };",
       record(hasName("C"), forEach(record(forEach(id("f", field()))))),
-      new VerifyIdIsBoundToDecl<clang::FieldDecl>("f", 4)));
+      new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
 }
 
 TEST(ForEachDescendant, BindsOneNode) {
   EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
       record(hasName("C"), forEachDescendant(id("x", field(hasName("x"))))),
-      new VerifyIdIsBoundToDecl<clang::FieldDecl>("x", 1)));
+      new VerifyIdIsBoundToDecl<FieldDecl>("x", 1)));
 }
 
 TEST(ForEachDescendant, BindsMultipleNodes) {
@@ -1898,7 +2106,7 @@
       "class C { class D { int x; int y; }; "
       "          class E { class F { int y; int z; }; }; };",
       record(hasName("C"), forEachDescendant(id("f", field()))),
-      new VerifyIdIsBoundToDecl<clang::FieldDecl>("f", 4)));
+      new VerifyIdIsBoundToDecl<FieldDecl>("f", 4)));
 }
 
 TEST(ForEachDescendant, BindsRecursiveCombinations) {
@@ -1907,7 +2115,7 @@
       "          class E { class F { class G { int y; int z; }; }; }; }; };",
       record(hasName("C"), forEachDescendant(record(
           forEachDescendant(id("f", field()))))),
-      new VerifyIdIsBoundToDecl<clang::FieldDecl>("f", 8)));
+      new VerifyIdIsBoundToDecl<FieldDecl>("f", 8)));
 }
 
 





More information about the cfe-commits mailing list